栈是一种基本数据结构,它的特点是后进先出,先进后出。可以类比取羽毛球,在球筒中后放进去的球是最先拿出来的。
要使用栈必须先包含<stack>。
#include<stack>
栈的基本操作有入(压)栈,出(退)栈,查找栈顶元素,获取栈元素个数,判空。代码实现如下:
#include<iostream>
#include<stack>
using namespace std;
int main()
{
stack<int> stk;//定义一个存放int类型元素的栈,栈名是stk
stk.push(1);//将1压入栈中
stk.push(2);//将2压入栈中
stk.push(3);//将3压入栈中
stk.pop();//将栈顶元素出栈
cout << stk.top() << endl; //.top返回的是栈顶元素的值
cout << stk.size() <<endl; // .size返回的是栈中元素的个数
cout << stk.empty() <<endl;// .empty返回的是栈是否为空,1表示为空,0表示栈中还有元素
return 0;
}
栈可以用来进行括号匹配等,相应的题目如下
苗苗今天刚刚学会使用括号,不过他分不清小括号,中括号,大括号和尖括号,不知道怎么使用这些括号,请帮助他判断括号使用是否正确。
输入格式
共一行,包含一个由 <
,(
,{
,[
,>
,)
,}
,]
构成的字符串。
输出格式
如果输入的字符串中的括号正确匹配则输出 yes
,否则输出 no
。
数据范围
输入字符串长度不超过 10000
输入样例:
(){}
输出样例:
yes
题目来源:Acwing第3693题,原题连接:括号匹配
题解如下:
#include<string>
#include<iostream>
#include<algorithm>
#include<stack>
using namespace std;
const int N = 10010;
char s[N];
int main()
{
scanf("%s",s);
stack<char> stk;
for(int i = 0; s[i]; i ++ )
{
if(s[i]=='(' || s[i]=='<' || s[i]=='[' || s[i]=='{') stk.push(s[i]);
else {
if(stk.size()==0)
{
cout <<"no"<<endl;
return 0;
}
if ((s[i] == '>' && stk.top() == '<') || (s[i] == ')' && stk.top() == '(') || (s[i] == ']' && stk.top() == '[') || (s[i] == '}' && stk.top() == '{'))
stk.pop();
else
{
cout << "no" << endl;
return 0;
}
}
}
if (stk.empty())
cout << "yes" << endl;
else
cout << "no" << endl;
return 0;
}
一个合法的括号字符串满足以下条件:
- 字符串“()”被认为是合法的。
- 如果字符串 “X” 与 “Y” 是合法的,则 “XY” 也被认为是合法的。
- 如果字符串 “X” 是合法的,则 “(X)” 也是合法的。
例如,“()”,“()()”,“(())” 这些都是合法的。
现在,给定一个由 (
和 )
组成的字符串 S
请你求出其中的最长合法括号子串的长度以及数量。
输入格式
共一行,一个由 (
和 )
组成的字符串。
输出格式
一行两个整数,表示最长合法括号子串的长度以及数量。
如果不存在合法括号子串,则输出 0 1
。
数据范围
前六个测试点满足:1≤|S|≤100
所有测试点满足:1≤|S|≤106
输入样例1:
)((())))(()())
输出样例1:
6 2
输入样例2:
))(
输出样例2:
0 1
题目来源:Acwing第30场周赛第2题,原题链接:最长合法括号子串
题解如下:
#include<string>
#include<iostream>
#include<algorithm>
#include<stack>
using namespace std;
const int N = 1000010;
char s[N];
int main()
{
scanf("%s",s);
stack<int> mys;
int resl = 0, resc = 1;
for (int i = 0; s[i]; i++)
{
if (mys.size() && s[i]==')' && s[mys.top()]=='(') mys.pop();
else mys.push(i);
int r;
if (mys.size()) r = i - mys.top(); //若没有进行出栈的操作,r为0,若进行了出栈的操作,r为当前的合法子串的长度
else r = i + 1;
if (r > resl) resl = r, resc = 1;
else if (r > 0 && r == resl) resc++; //如果有相同长度的最长子串,resc加1
}
printf("%d %d\n",resl,resc);
return 0;
}
另外,考研中也会涉及到栈的运用,例如:
1. 一个栈的入栈序列是abcde,则栈的不可能的输出序列是_____(南京航空航天大学 2011年)
A.edcba
B.decba
C.dceab
D.abcde
正确答案为C
A选项中,abcde依次入栈然后依次出栈即可达成此输出序列。
B选项中,abcd先入栈,然后d出栈,e进栈,e出栈,abc再依次出栈即可达成此输出序列。
C选项错误,不可能达成此输出序列。
D选项中,a入栈,a出栈,b入栈,b出栈....e入栈,e出栈即可达成此输出序列。
此外,有n个元素的栈,出栈元素排序的方式共有种,这个数也被称为卡特兰数。