实现方式:数组+栈顶指针
Int sta[maxn]
Int top
操作:
Void push(x):入栈
Top++;
sta[top]=x;
void pop(x):出栈
top--;
int top():查询栈顶元素
return sta[top]
int empty():
if(top==0)return 1;
return 0;
int size():
return top+1;
栈的应用:
- 括号匹配
例题:洛谷P1739
因为只涉及到计数所以构建一个虚拟栈,输入字符c,如果输入字符为”(“,则入栈,top++,若输入字符为”)”,若栈不为空,则弹出栈顶元素与右括号匹配,top--,若栈为空,则输出”NO”,结束程序,输入字符为”@”,结束输入,检查栈是否为空,若为空则匹配完全,不为空则有剩余左括号未匹配,输出“NO”.
//程序说明:栈的数组实现
#include<bits/stdc++.h>
using namespace std;
//int sta[256];
char c;
int top;//栈顶指针虚拟栈
int main()
{
while(cin>>c){
if(c=='@')break;
if(c=='(')top++;
if(c==')'&&top>0)top--;
else if(c==')'&&top==0){
cout<<"NO";
return 0;
}
}
if(top==0)cout<<"YES";
else cout<<"NO";
return 0;
}
- 表达式求值
- 后缀表达式,不用考虑优先级,只需构建一个数据栈,实现较为简单
例题:洛谷(P1449)
#include<bits/stdc++.h>
using namespace std;
char c;
int sta[1001];
int top=-1;
int num,t;
int main()
{
while(cin>>c){
if(c=='@')break;
if(c=='.'){
top++;
sta[top]=num;
num=0;
}
else if(c>='0'&&c<='9')num=num*10+c-'0';
else{
switch(c){
case '-':
t=sta[top-1]-sta[top];
top--;
sta[top]=t;
break;
case '+':
t=sta[top]+sta[top-1];
top--;
sta[top]=t;
break;
case '*':
t=sta[top]*sta[top-1];
top--;
sta[top]=t;
break;
case '/':
t=sta[top-1]/sta[top];
top--;
sta[top]=t;
break;
}
}
}
cout<<sta[top];
return 0;
}
2. 中缀表达式求值
构建两个栈,一个栈装载数字,一个栈装载运算符,如何处理运算符优先级?在运算符入栈过程中,如果当前运算符优先级低于栈顶优先级,则栈顶优先级出栈运算后当前运算符入栈,左括号则直接入栈,遇到右括号则while向下扫描,抛出括号内运算符并计算,直到遇到左括号。最后,两个栈中剩余元素可直接匹配运算,运算结束,输出数字栈栈顶元素。
例题:(洛谷 P1981)
#include<bits/stdc++.h>
using namespace std;
int sta1[100001];
int top1=-1,top2=-1,num,ans;
int sta2[100001];
int main()
{
string s;
cin>>s;
for(int i=0;i<s.length();i++){
//数字part
if(i==s.length()-1&&s[i]>='0'&&s[i]<='9'){
ans=ans*10+s[i]-'0';
top1++;
sta1[top1]=ans%100000;
}
if(s[i]>='0'&&s[i]<='9'){
ans=ans*10+s[i]-'0';
}
//字符part
else{
//第一步结算数字入栈
top1++;
sta1[top1]=ans%100000;
ans=0;
//第二步处理字符
if(s[i]=='('){//左括号直接入
top2++;
sta2[top2]=0;
continue;
}
else if(s[i]==')'){//右括号,清算括号内容
while(sta2[top2]!=0){//直到遇到左括号
switch(sta2[top2]){//运算
case 1:
num=sta1[top1-1]+sta1[top1];
top1--;
sta1[top1]=num%100000;
break;
case 2:
num=sta1[top1-1]-sta1[top1];
top1--;
sta1[top1]=num%100000;
break;
case 3:
num=sta1[top1-1]*sta1[top1];
top1--;
sta1[top1]=num%100000;
break;
case 4:
num=sta1[top1-1]/sta1[top1];
top1--;
sta1[top1]=num%100000;
break;
}
}
top2--;//清除左括号
continue;
}
//非括号字符
int sym;//为运算符确定标志数
switch(s[i]){
case '+':sym=1;break;
case '-':sym=2;break;
case '*':sym=3;break;
case '/':sym=4;break;
}
if((sym==1||sym==2)&&(sta2[top2]==3||sta2[top2]==4)){//优先级低要先抛出栈顶的运算符
switch(sta2[top2]){//计算
case 1:
num=sta1[top1-1]+sta1[top1];
top1--;
sta1[top1]=num%100000;
break;
case 2:
num=sta1[top1-1]-sta1[top1];
top1--;
sta1[top1]=num%100000;
break;
case 3:
num=sta1[top1-1]*sta1[top1];
top1--;
sta1[top1]=num%100000;
break;
case 4:
num=sta1[top1-1]/sta1[top1];
top1--;
sta1[top1]=num%100000;
break;
}
sta2[top2]=sym;//字符入栈
}
else{//优先级更高,压住
top2++;
sta2[top2]=sym;
}
}
}
//结算
while(top2>=0){
switch(sta2[top2]){
case 1:
num=sta1[top1-1]+sta1[top1];
top1--;
sta1[top1]=num%100000;
break;
case 2:
num=sta1[top1-1]-sta1[top1];
top1--;
sta1[top1]=num%100000;
break;
case 3:
num=sta1[top1-1]*sta1[top1];
top1--;
sta1[top1]=num%100000;
break;
case 4:
num=sta1[top1-1]/sta1[top1];
top1--;
sta1[top1]=num%100000;
break;
}
top2--;
}
cout<<sta1[top1]%10000;//输出最终结果
return 0;
}