堆栈操作合法性
题目:假设以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
解法一:用函数+堆栈实现
#include <iostream>
#include <stack>
using namespace std;
bool is_right(string line, int stack_max_size); // stack_max_size:堆栈的最大容量
int main()
{
int n, m;
cin >> n >> m;
cin.ignore(); // 跳过换行符
// 等同于getchar();
// 输入n行字符串
for (int i = 0; i < n; i++)
{
string line;
getline(cin, line);
// 调用函数
if (is_right(line, m))
cout << "YES" << endl;
else
cout << " NO" << endl;
}
}
bool is_right(string line, int stack_max_size)
{
stack<int> INT_STACK;
for (int i = 0; i < line.size(); i++)
{
if (line[i] == 'S')
{
// 若当前堆栈长度的大于或等于堆栈的最大容量,return false;否则,压栈
if (INT_STACK.size() >= stack_max_size)
return false;
INT_STACK.push(i);
}
else if (line[i] == 'X')
{
// 若当前堆栈为空,return false;否则,弹栈
if (INT_STACK.empty())
return false;
INT_STACK.pop();
}
}
return INT_STACK.empty();
}
解法二:stack法
#include <iostream>
#include <stack>
using namespace;
int main()
{
int n, m;
cin >> n >> m;
getchar();
string s;
while (n--)
{
stack<char> c_stack; // 将堆栈定义在内部,可实现每轮循环字符串的清空
//s.clear(); // 若堆栈定义在外部,即可用s.clear()实现每轮字符串的清空
getline(cin, s);
int count = 0;
for (int i = 0; i < s.size(); i++)
{
if (s[i] == 'S')
{
c_stack.push(s[i]); // 压栈
count++;
if(count > m)
{
cout << "NO" << endl;
break;
}
}
else if (s[i] == 'X')
{
c_stack.pop(); // 弹栈
count--;
if(count < 0)
{
cout << "NO" << endl;
break;
}
}
}
if (c_stack.empty() && count == 0)
cout << "YES" << endl;
else
cout << "NO"<< endl;
}
return 0;
}
解法三:string法
#include <iostream>
#include <string>
using namespace std;
int main()
{
int n, m; // 输入4 10
cin >> n >> m;
getchar();
string str;
while (n--)
{
int count = 0;
str.clear(); // 清空字符串
getline(cin, str); // 输入一行字符串
for (int i = 0; i < str.length(); i++)
{
if (str[i] == 'S' && count < m) // S:入栈
count++;
else if (str[i] == 'X' && count > 0) // X:出栈
count--;
else
break;
}
if (i == str.length() && count == 0)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}
小结
堆栈
一.是什么?
1.堆栈:是一种模板容器适配器,以“先进后出”的方式访问容器内的元素。(简称:LIFO线性表)
二.定义及操作
1.头文件
#include <stack>
2.定义
stack <int> s;
3.操作:(成员函数)【重点】
s.push(); // 在栈顶压入新元素
s.top(); // 返回栈顶元素
s.pop(); // 移除栈顶元素
s.size(); // 返回栈中元素的数目
s.empty(); // 堆栈为空返回true
三.应用时机及实例
1.应用时机
1.1.存储一批数
1.2.以“先进后出”的顺序访问这批数
2.实例 【掌握】
2.1.回文判断
2.2.括号匹配
四.大小比较(了解即可)
1.两个堆栈之间的大小关系基于首对不相等元素之间的比较。
2.如果两个堆栈具有元素数目相同且对应元素具有相同的值,则两个列表相等。