描述:
如果以序列“1,2,3,4”作为一个栈(初始为空)的输入,那么可得到输出序列“1,2,3,4”或“4,3,2,1”或“2,3,1,4”等等,但是肯定得不到输出序列“4,1,2,3”或“3,1,2,4”等等。请编写一个程序,判断能否通过一个栈得到给定的输出序列。
输入说明:
每组数据由两行构成,第一行只有一个整数n(<10),表示序列长度,同时表示栈的输入序列为“1,2,3,…,n”;第二行为n个整数,表示需要判断的出栈序列,整数之间以空格分隔。
输出说明:
输出一个yes或no(表示能否通过栈得到该序列)。
输入样例:
6
3 4 2 1 5 6
输出样例:
yes
提示
根据栈的后进先出特性进行判断
解决思路:
由于出栈序列有太多可能,不能一一列举出来,所以采用检验出栈序列元素的方式。循环依据是每循环一次,就会出栈一个元素,就可以对一个出栈序列元素进行检验,所以要循环n次,每次循环可分为三种情况:
一种是栈顶元素小于出栈序列元素,那应该一直入栈,直到该出栈序列元素入栈(所以采用循环);
一种是栈顶元素等于出栈序列元素,让栈顶元素出栈即可。然后直接进入下一次循坏,开始检验下一位出栈序列元素;
还有一种是栈顶元素大于出栈序列元素,例如出栈序列元素要求是2,而此时栈顶元素是3,2是不能比上面的3先出栈的,直接说明这个出栈序列是得不到的,循环也没有必要继续了
如果最后栈的元素都出栈成功了,则说明可以得到该输出序列。
此外,由于一开始栈是空的,*(s.top-1)和a【i】可能没法比较,就让它先入栈一个元素
PS:本人很菜,写的可能不完全对,如果发现有疏忽的地方可以指出来(XDOJ是通过了的)
完整代码
#include<stdio.h>
#include<stdlib.h>
#define STACK_SIZE 15
typedef struct{
int *base;
int *top;
int stacksize;
}SqStack;
void InitStack(SqStack *s){
(*s).base=(int*)malloc(STACK_SIZE*sizeof(int));
(*s).top=(*s).base;
(*s).stacksize=STACK_SIZE;
}//InitStack
void Push(SqStack *s,int e){
*((*s).top)=e;
(*s).top++;
}//Push
int Pop(SqStack *s){
int e;
--(*s).top;
e=*((*s).top);
return e;
}//Pop
int main(){
int n,i,j,result;
int a[15];
SqStack s;
InitStack(&s);
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
j=1;
for(i=0;i<n;i++){
if(s.base==s.top){
Push(&s,j);
j++;
}
while(*(s.top-1)<a[i]){
Push(&s,j);
j++;
}
if(*(s.top-1)=a[i]){
Pop(&s);
continue;
}
if(*(s.top-1)>a[i]){
result=0;
printf("no");
break;
}
}
if(s.top==s.base) result=1;
if(result) printf("yes");
else printf("no");
return 0;
}