题目:
假设S和X分别为表示入栈和出栈操作。如果根据一个仅由S和X构成的序列,对一个空堆栈进行操作,相应操作均可行(如没有出现删除时栈空)且最后状态也是栈空,
则称该序列是合法的堆栈操作序列。
编写程序,输入S和X序列,判断该序列是否合法。
要求:
(1)输入说明:第一行给出两个正整数M和N,其中M是待测序列的个数,N(N<=50)是堆栈最大容量。
随后M行,每行给出一个仅由S和X构成的序列,序列保证不为空,且长度不超过100
(2)输出说明:
对每个序列,如果该序列是合法的堆栈操作序列,在一行中输出YES,否则输出NO。
(3)测试:
3 10
S NO
SX YES
SSSXXSXXSX NO
1 #include <stdio.h> 2 #include <stdbool.h> 3 #include <stdlib.h> 4 #define MaxN 101 5 6 typedef struct SNode *Stack; 7 struct SNode{ 8 int *Data; 9 int Top; 10 int MaxSize; 11 }; 12 13 Stack CreatStack(int maxsize){ 14 Stack S=(Stack)malloc(sizeof(struct SNode)); 15 S->Data=(int*)malloc(sizeof(int)*maxsize); 16 S->Top=-1; 17 S->MaxSize=maxsize; 18 return S; 19 } 20 21 bool IsEmpty(Stack S){ 22 23 return (S->Top==-1); 24 } 25 26 bool IsFull(Stack S){ 27 28 return (S->Top==S->MaxSize-1); 29 } 30 31 bool Push(Stack S,int x){ 32 33 if(IsFull(S)){ 34 return false; 35 }else{ 36 S->Data[++(S->Top)]=x; 37 return true; 38 } 39 } 40 41 bool Pop(Stack S){ 42 43 if(IsEmpty(S)){ 44 return false; 45 }else{ 46 S->Top--; 47 return true; 48 } 49 } 50 51 void Clear(Stack S){ 52 while(!IsEmpty(S)){ 53 Pop(S); 54 } 55 56 } 57 58 int main(){ 59 int i,j,M,N; 60 char str[MaxN]; 61 scanf("%d%d\n",&M,&N); 62 Stack S=CreatStack(N); 63 64 for(i=0;i<M;i++){ 65 scanf("%s",str); 66 Clear(S); 67 68 for(j=0;str[j]!=‘\0‘;j++){ 69 if((str[j]==‘S‘) && (!Push(S,1))){ 70 break; 71 } 72 if((str[j]==‘X‘) && (!Pop(S))){ 73 break; 74 } 75 } 76 if((str[j]==‘\0‘) && IsEmpty(S)){ 77 printf("Yes\n"); 78 }else{ 79 printf("No\n"); 80 } 81 } 82 83 84 return 0; 85 }
分析:
用一个循环来处理每个序列。在一次循环里,将待处理的序列读入一个字符串中,然后逐一检查每个字符:如果是S,就检查入栈是否成功(如果堆栈已满就会不成功);如果是X,就检查出栈是否成功(如果堆栈已空就会不成功)。最后当所有字符都处理完时,检查当前堆栈是不是正好空了,如果还没空也要报错。
实现要点:
实现程序的过程中并不关心堆栈里的元素是什么,只关心这个操作能不能执行,所以入栈时把什么元素压入栈中都可以;出栈时不管出栈的元素是什么,只需把Top减1就可以了,当然要返回出栈是否成功的标识。
每次循环要处理一个新序列时,必须把上次循环后的可能残留在堆栈中的元素清空。
原文:https://www.cnblogs.com/hpthinking/p/12098369.html