堆栈模拟/pta_02_线性结构4_Pop_Sequence
前言:写这个的原因就是同学问了我咋写,我当时也不太懂,花了一下午写了一份代码,这里做个记录
题目内容
Given a stack which can keep M numbers at most. Push N numbers in the order of 1, 2, 3, …, N and pop randomly. You are supposed to tell if a given sequence of numbers is a possible pop sequence of the stack. For example, if M is 5 and N is 7, we can obtain 1, 2, 3, 4, 5, 6, 7 from the stack, but not 3, 2, 1, 7, 5, 6, 4.
给定一个最多可以保存M个数字的堆栈。按1、2、3、…的顺序按N个数字, N和随机弹出。您应该知道给定的数字序列是否可能是堆栈的弹出序列。例如,如果M是5,N是7,我们可以从堆栈中得到1,2,3,4,5,6,7,而不是3,2,1,7,5,6,4。
输入样式
Each input file contains one test case. For each case, the first line contains 3 numbers (all no more than 1000): M (the maximum capacity of the stack), N (the length of push sequence), and K (the number of pop sequences to be checked). Then K lines follow, each contains a pop sequence of N numbers. All the numbers in a line are separated by a space.
每个输入文件包含一个测试用例。对于每种情况,第一行包含3个数字(都不超过1000):M(堆栈的最大容量)、N (push序列的长度)和K(要检查的pop序列的数量)。然后接着K行,每一行包含一个由N个数字组成的弹出序列。一行中的所有数字用一个空格隔开。
输出样式
For each pop sequence, print in one line “YES” if it is indeed a possible pop sequence of the stack, or "NO" if not.
对于每个弹出序列,如果它确实是一个可能的堆栈弹出序列,则打印一行“YES”,如果不是,则打印“NO”
输入数据
5 7 5
1 2 3 4 5 6 7
3 2 1 7 5 6 4
7 6 5 4 3 2 1
5 6 4 3 7 2 1
1 7 6 5 4 3 2
输出结果
YES
NO
NO
YES
NO
代码如下,写的有点勉强,其实上面的题目的意思就是给定一串字符串,让你来判断通过1-n的数字是否能够在堆栈中通过压入弹出,最终获得题目给出的字符串,如果可以的话,那么就输出"Yes",不可以就输出"No"
#define _CRT_SECURE_NO_WARNINGS
#define MAXSIZE 1001
#define STACKSIZE 10
#include<stdio.h>
#include<stdlib.h>
int main() {
int m, n, k; // m最大堆栈容量 n序列长度 k序列的总数量 , m=5 n=7 k=5
scanf("%d %d %d", &m, &n, &k);
// 总共存在几组序列,就遍历这几组序列
for (int i = 0; i < k; i++)
{
int inputBuffer[MAXSIZE] = { 0 };
int stackArray[MAXSIZE] = { 0 }; // 模拟栈结构
int Array[MAXSIZE] = { 0 }; // 默认顺序存储 1-n 的数
int resArray[MAXSIZE] = { 0 }; // 存放每组序列最终出栈完存储的值
// initArr
for (int initIndex = 0; initIndex < n; initIndex++)
Array[initIndex] = initIndex + 1;
int currentArrayLength = 0; // 作为栈顶的索引计数器
for (int j = 0; j < n; j++)
{
scanf("%d", &inputBuffer[j]);
if (j < n - m && inputBuffer[j] > n - 1)
{
// 特殊情况的处理,如果每次序列组中的第j个值是直接大于堆栈容量大小+j的话,那么这输入的序列的情况是不存在的
// 剩余在缓冲区的字符还需要进行处理
char ch; while ((ch = getchar()) != '\n' && ch != EOF);
break;
}
if (inputBuffer[j] > m + j)
{
// 特殊情况的处理,如果每次序列组中的第j个值是直接大于堆栈容量大小+j的话,那么这输入的序列的情况是不存在的
// 剩余在缓冲区的字符还需要进行处理
char ch; while ((ch = getchar()) != '\n' && ch != EOF);
break;
}
// 接下来就是正常的情况处理
// 孙总的BUG: 3 2 1 5 7 4 6
int currentArrayIndex = 0;
int flag = 0;
for (int p = 0; p < n - j; p++)
{
// 模拟压栈, 这里的currentArrayLength相当于栈顶的指针
// 如果遍历的时候每次都不等于 Data[p] 的话,那么都先压入到栈中
// 不等于的时候有两种情况:
// 1. inputBuffer[j] 比当前currentArrayLength指向的大
// 2. inputBuffer[j] 比当前currentArrayLength指向的小
if (Array[currentArrayLength] != inputBuffer[j]) // && stackArr[currentArrayIndex] != Data[j]
{
// 当inputBuffer[j] 比当前currentArrayLength指向的小的时候,这时候也有两种情况
// 2.1 inputBuffer[j] - stackArray[currentArrayLength-1] = 1
// 2.2 inputBuffer[j] - stackArray[currentArrayLength-1] > 1
if (stackArray[currentArrayLength - 1] == inputBuffer[j])
{
// 模拟出栈操作,首先stackArray中currentArrayLength所指向的得出来
resArray[j] = stackArray[currentArrayLength - 1];
// 然后还需要清空当前的currentArrayLength为0
stackArray[currentArrayLength - 1] = 0;
//currentArrayLength--; // 每次入栈/入栈,当前栈顶的位置currentArrayLength都需要发生变动
for (int currentPosition = currentArrayLength - 1; currentPosition < n; currentPosition++)
{
Array[currentPosition] = Array[currentPosition + 1];
}
currentArrayLength--;
break;
}
// 如果要入栈,此时在入栈之前还需要判断下当前堆栈的容量是否充足
// 这里在 压栈之前判断最后一个压入的元素的索引值 是否等同于 当前堆栈的容量大小
/*
int countNum = 0;
while (*(stackArray+countNum))
{
countNum++;
if (countNum == m)
{
flag = 1;
break;
}
}
if (flag == 1)
break;
*/
// inputBuffer[j] 比当前currentArrayLength指向的大
// 3 2 1 5 7 4 6
// 并且此时堆栈容量还足够,所以可以进行压入操作
/*
int flag2 = 0;
for (int o = 0; o < currentArrayLength+1; o++)
{
if (stackArray[o] == Array[o])
continue;
else
{
stackArray[o] = Array[o];
currentArrayIndex++;
currentArrayLength++; // 每次入栈/入栈,当前栈顶的位置currentArrayLength都需要发生变动
flag2 = 1;
break;
}
}
if (flag2)
break;
*/
/*
while (stackArray[tmp] == Array[tmp])
{
// int tmp = currentArrayIndex;
tmp++;
// stackArray[tmp] = Array[tmp];
// currentArrayIndex++;
// currentArrayLength++;
}*/
/*
int tmp = currentArrayIndex;
if (stackArray[tmp] == Array[tmp])
{
int tmp = currentArrayIndex;
tmp++;
stackArray[tmp] = Array[tmp];
currentArrayIndex++;
currentArrayLength++;
continue;
}
*/
// inputBuffer[j] 比当前currentArrayLength指向的大
// 并且此时堆栈容量还足够,所以可以进行压入操作
stackArray[currentArrayLength] = Array[currentArrayLength];
currentArrayIndex++;
currentArrayLength++; // 每次入栈/入栈,当前栈顶的位置currentArrayLength都需要发生变动
}
else if (stackArray[currentArrayLength] == inputBuffer[j])
{
resArray[j] = inputBuffer[j];
// 修正
stackArray[currentArrayLength] = 0;
}
else{
// 如果栈顶的值等于所需要的序列[j]的值,那么此时就模拟出栈操作,并且修正位置
resArray[j] = Array[currentArrayLength];
//currentArrayLength--; // 每次入栈/入栈,当前栈顶的位置currentArrayLength都需要发生变动
for (int currentPosition = currentArrayLength; currentPosition < n; currentPosition++)
{
Array[currentPosition] = Array[currentPosition + 1];
}
break;
}
}
if (flag == 1)
break;
}
// 最终进行序列判断
for (int count = 0; count < n; count++)
{
if (resArray[count] != inputBuffer[count])
{
printf("NO\n");
break;
}
if (count == (n - 1))
{
printf("YES\n");
break;
}
}
}
return 0;
}

上个图


浙公网安备 33010602011771号