目录
一.栈与顺序栈的基础概念
二.PTA题目理解
三.代码展示
一.栈与顺序栈的基础概念
栈是线性表的一种,但是受限制的线性表,即只允许从一端插入和删除数据(先入后出)。也因为栈属于线性表,栈也有两种存储方式,即线性存储和链式存储。栈的一个的特征就是栈的插入和删除只能在栈顶进行,
(图片来源知乎)
有关栈的链式存储今天不做介绍,本题就是用顺序栈实现。
有关顺序栈,可以理解为一个栈类型连续存储空间(数组),栈底指针base指向这个连续存储空间(数组)的首地址,通过栈顶top指针在该连续存储空间(数组)移动来实现出入栈。不含元素称为空栈(即top指向base指针所指向的存储空间(数组)首地址时)。
具体了解可点击
二.PTA题目理解
题目:
假设以S
和X
分别表示入栈和出栈操作。如果根据一个仅由S
和X
构成的序列,对一个空堆栈进行操作,相应操作均可行(如没有出现删除时栈空)且最后状态也是栈空,则称该序列是合法的堆栈操作序列。请编写程序,输入S
和X
序列,判断该序列是否合法。
输入格式:
输入第一行给出两个正整数N和M,其中N是待测序列的个数,M(≤50)是堆栈的最大容量。随后N行,每行中给出一个仅由S
和X
构成的序列。序列保证不为空,且长度不超过100。
输出格式:
对每个序列,在一行中输出YES
如果该序列是合法的堆栈操作序列,或NO
如果不是。
————————————————————————————————————
理解程序输入:输入N个待测个数(即N个栈)(可动态创建N个栈),与栈最大存储空间M,然后每一行(对应每一个栈)给出一字符串str(可利用循环输入N次字符串,对N个栈进行操作)(里面每个str[i]为一个操作)。
对于输入样例:
4 10
SSSXXSXXSX //没有满栈时入栈,空栈时出栈,最后执行X后栈空;合法yes
SSSXXSXXS //入栈数不等于出栈数,结束时栈不为空,不合法no
SSSSSSSSSSXSSXXXXXXXXXXX //在栈满(第12个S)时还入栈,不合法no
SSSXXSXXX //入栈数不等于出栈数,栈空时还出栈,不合法no
三.代码展示
#include<iostream>
#include<string>
using namespace std;
typedef struct Stack {
int* top;
int* base;
int stacksize;
}Stack;//建立顺序栈
bool iniStack(Stack& S, int size);//初始化栈
bool push(Stack& S, int x);//入栈
bool pop(Stack& S, int& x);//出栈
bool iniStack(Stack& S, int size) {//因题目需要判断栈合法性,选择bool返回型
S.stacksize = size;
S.base = new int[size];//动态建立一连续的int型存储空间,令栈底指针指向该存储空间的首地址
S.top = S.base;//top也指向该存储地址的首地址,
//但base指针是不移动的,是通过top指针的移动进行出入栈
if (!S.base)
return false;
else
return true;
}
bool push(Stack& S, int x) {//依旧使用bool返回型,
if (S.top - S.base == S.stacksize)//若栈满,操作不合法
{
return false;
}
else
{
*S.top = x;//入栈
S.top++;//将top指针上移一个到地址值更高的存储单元,等待下一次入栈
//如果x是第[stacksize-1]个元素,则top也上移到高地址空间,此时满栈,下一次输入则不合法
return true;
}
}
bool pop(Stack& S, int& x) {//依旧使用bool返回型,
if (S.top == S.base)//若栈空,则操作不合法
{
return false;
}
else
{
S.top--;//top指针下移并指向即将被出栈元素
x = *S.top;
return true;
}
}
int main()
{
Stack* S;//创建指向栈类型的指针;
int n;//N
int m;//M
int x;//入栈值
int x0;//出栈值
bool status = true;
string str;
cin >> m >> n;
S = new Stack[m];//动态分配题目所给的m次判断,对应m个栈
for(int i=0;i<m;i++)
{
status=iniStack(S[i], n);
cin >> str;//接受题目每次给出的SX字符串
for (int j = 0; j < str.length(); j++)
{
if(str[j]=='S')//入栈操作
{
status = push(S[i], 1);//因题目仅进行操作,无特特定输入值,我们选择输入1
//根据status布尔值判断操作合法性
}
else if(str[j]=='X')//出栈操作
{
status = pop(S[i], x0);因题目无需输出值,我们用x0仅接收;
//根据status布尔值判断操作合法性
}
}
if (status && S[i].base == S[i].top)//若操作过程中操作合法且结束时栈空输出YES
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}