栈的基本操作 栈的相关操作可使用C++模板库里的函数
#include<stack>
using namespace std;
定义一个栈
stack<int> S;
S.push(i); 将数值i压入栈
int x=S.top(); 读取栈顶元素
S.pop(); 弹出栈顶元素
例1. 九度1153 括号匹配问题
题目描述:
在某个字符串(长度不超过100)中有左括号、右括号和大小写字母;规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。写一个程序,找到无法匹配的左括号和右括号,输出原来字符串,并在下一行标出不能匹配的括号。不能匹配的左括号用"$"标注,不能匹配的右括号用"?"标注.
输入:
输入包括多组数据,每组数据一行,包含一个字符串,只包含左右括号和大小写字母,字符串长度不超过100。
注意:cin.getline(str,100)最多只能输入99个字符!
输出:
对每组输出数据,输出两行,第一行包含原始输入字符,第二行由"$","?"和空格组成,"$"和"?"表示与之对应的左括号和右括号不能匹配。
样例输入:
)(rttyy())sss)(
样例输出:
)(rttyy())sss)(
? ?$
来源:
2010年北京大学计算机研究生机试真题
#include<stdio.h>
#include<stack>
using namespace std;
stack<int> S;
int main(int argc, char* argv[])
{
char str[110];
char ans[110];
while(scanf("%s",str)!=EOF)
{
int i;
for(i=0;str[i]!='\0';i++) //遍历字符串数组
{
if(str[i]=='('){ //如果是左括号 入栈
S.push(i);
ans[i]=' ';
}
else if(str[i]==')') //如果是右括号,再判断栈中是否有左括号
{
if(!S.empty())
{
S.pop();
ans[i]=' ';
}
else{
ans[i]='?';
}
}
else ans[i]=' ';
}
while(!S.empty()) //判断栈中是否还有剩余左括号
{
ans[S.top()]='$';
S.pop();
}
ans[i]='\0';
puts(str);
puts(ans);
}
return 0;
}
例2 九度1019 简单计算器(一点也不简单 很麻烦但是很重要)
-
题目描述:
-
读入一个只包含 +, -, *, / 的非负整数计算表达式,计算该表达式的值。
-
输入:
-
测试输入包含若干测试用例,每个测试用例占一行,每行不超过200个字符,整数和运算符之间用一个空格分隔。没有非法表达式。当一行中只有0时输入结束,相应的结果不要输出。
-
输出:
-
对每个测试用例输出1行,即该表达式的值,精确到小数点后2位。
#include<stdio.h>
#include<stack>
using namespace std;
char str[220];
int mat[][5]={
1,0,0,0,0,
1,0,0,0,0,
1,0,0,0,0,
1,1,1,0,0,
1,1,1,0,0
};
stack<int> op; //定义运算符栈
stack<double> in;//定义数字栈
void getOp(bool &reto,int &retn,int &i)//获得表达式下一元素函数
{
if(i==0&&op.empty()) //人为添加标记为0的运算符
{
reto=true;
retn=0;
return;
}
if(str[i]==0) //字符串被遍历结束,返回标记为0的标记字符
{
reto=true;
retn=0;
return;
}
if(str[i]>='0'&&str[i]<='9')
{
reto=false;
}
else{
reto=true;
if(str[i]=='+') retn=1;
else if(str[i]=='-') retn=2;
else if(str[i]=='*') retn=3;
else if(str[i]=='/') retn=4;
i+=2;
return;
}
retn=0;
for(;str[i]!=' '&&str[i]!=0;i++) //如果下一个字符不是空格且字符串没遍历完,说明下一个是连续数字
{
retn*=10;
retn+=str[i]-'0';
}
if(str[i]==' ')
{
i++;
return;
}
}
int main(int argc, char* argv[])
{
while(gets(str)){
if(str[0]=='0'&&str[1]==0) break;
bool retop;
int retnum;
int idx=0;
while(!op.empty()) op.pop(); //清空运算符栈
while(!in.empty()) in.pop(); //清空数字栈
while(true){ //循环遍历字符串
getOp(retop,retnum,idx);
//若该元素为数字
if(retop==false)
{
in.push((double)retnum);
}
else{
double tmp;
//如果当前运算符优先级高或者栈为空的话就将该运算符压入栈
if(op.empty()||mat[retnum][op.top()]==1)
{
op.push(retnum);
}
//如果栈顶运算符优先级高的话,就进行循环遍历
else{
while(mat[retnum][op.top()]==0)
{
int ret=op.top();
op.pop();
double b=in.top();
in.pop();
double a=in.top();
in.pop();
if(ret==1) tmp=a+b;
else if(ret==2) tmp=a-b;
else if(ret==3) tmp=a*b;
else tmp=a/b;
in.push(tmp);
}
op.push(retnum); //当没有栈中优先级更高的时候,要记得把当前运算符放入栈中
}
}
if(op.size()==2&&op.top()==0) break; //若栈中只有两个元素且栈顶元素为标记运算符,表达式求值结束
}
printf("%.2f\n",in.top());
}
return 0;
}