注:数据结构中对堆栈基本操作的简化综合题(仅做个人笔记记录)
题目
假设以S和X分别表示入栈和出栈操作。如果根据一个仅由S和X构成的序列,对一个空堆栈进行操作,相应操作均可行(如没有出现删除时栈空)且最后状态也是栈空,则称该序列是合法的堆栈操作序列。请编写程序,输入S和X序列,判断该序列是否合法。
输入格式:
输入第一行给出两个正整数N和M,其中N是待测序列的个数,M(≤50)是堆栈的最大容量。随后N行,每行中给出一个仅由S和X构成的序列。序列保证不为空,且长度不超过100。
输出格式:
对每个序列,在一行中输出YES如果该序列是合法的堆栈操作序列,或NO如果不是。
输入样例:
4 10
SSSXXSXXSX
SSSXXSXXS
SSSSSSSSSSXSSXXXXXXXXXXX
SSSXXSXXX
输出样例:
YES
NO
NO
NO
题解记录:
通过循环读入每个序列,然后逐个检查字符,如果是S,入栈(栈满返回false),如果是X,出栈(栈空返回false)
代码:
定义堆栈及函数声明
#include<stdio.h>
#include<stdlib.h>
#define MAXS 101
#define MAXN 50
typedef enum { False, True }Bool;
typedef int ElementType;
//堆栈定义
typedef int Position;
typedef struct SNode* PtrToSNode;
struct SNode {
ElementType* Data;
Position Top;
int Maxsize;
};
typedef PtrToSNode Stack;
Stack CreateStack(int Maxsize);//构造堆栈
bool IsEmpty(Stack S);//判断是否为空
bool IsFull(Stack S);//判断是否已满
bool Push(Stack S,ElementType X);//入栈
bool Pop(Stack S);//出栈
void Clear(Stack S);//每次循环处理新序列,必须把上次循环可能残留的元素清空
主程序
int main() {
int N, M, i, j;
char Str[MAXS];
Stack S;
scanf("%d %d\n", &N, &M);
S = CreateStack(M);
for (i = 0; i < N; i++) {
scanf("%s", Str);
Clear(S);
for (j = 0; Str[j] != '\0'; j++) {
if ((Str[j] == 'S') && (!Push(S, 1)))break;
if ((Str[j] == 'X') && (!Pop(S)))break;
}
if ((Str[j] == '\0') && IsEmpty(S))printf("YES\n");
else printf("NO\n");
}
return 0;
}
函数
Stack CreateStack(int Maxsize) {
Stack S = (Stack)malloc(sizeof(struct SNode));
S->Data = (ElementType*)malloc(Maxsize * sizeof(ElementType));
S->Top = -1;
S->Maxsize = Maxsize;
return S;
}
bool IsEmpty(Stack S) {
return (S->Top == -1);
}
bool IsFull(Stack S) {
return (S->Top == (S->Maxsize - 1));
}
bool Push(Stack S, ElementType X) {
if (IsFull(S)) return false;
else {
S->Data[++(S->Top)] = X;
return true;
}
}
bool Pop(Stack S) {
if (IsEmpty(S)) return false;
else {
(S->Top)--;
return true;
}
}
void Clear(Stack S) {
while(!IsEmpty(S))Pop(S);
}