#题目描述#
小明希望破破一个密码门。门上有一个算式,其中只有“(”、“)”、“0-9”、“+”、“-”、“*”、“/”、“^”,求出的值就是密码。小明的数学学得不好,还需你帮他的忙。(“/”用整数除法)
#输入格式#
一个只有一行的算式(算式长度<=30)。
#输出格式#
输出算式的值(所有数据在2^31-1范围内)。
#样例数据#
input
1+(3+2)*(7^2+6*9)/(2)
output
258
#分析#
这道题只需要建立两个栈:
1)记录所有的符号
2)记录所有的数字
数字我们只需要像减一下ACSCLL码处理(注意:不一定是一位数),但是符号有先后顺序。所以我们在每次放入一个符号的时候必须先确认一下这个符号的优先级,如果比前一个符号的优先级低,那就先完成前面的运算再将这个符号放入栈中。不然直接放入(如果它的前一个字符是'(',特判退出)。
#代码#
#include<bits/stdc++.h>
using namespace std;
string s;
char sym[100100]={};//建立一个字符栈
int num[100100]={};//建立一个数字栈
int head1;//字符栈的栈顶
int head2;//数字栈的栈顶
int check(char a)
{
if(a=='+'||a=='-')
return 1;//第一运算
if(a=='*'||a=='/')
return 2;//第二运算
if(a=='^')
return 3;//第三运算
}
void cumpute()
{
head2--;
if(sym[head1]=='+')
num[head2]+=num[head2+1];
if(sym[head1]=='-')
num[head2]-=num[head2+1];
if(sym[head1]=='*')
num[head2]*=num[head2+1];
if(sym[head1]=='/')
num[head2]/=num[head2+1];
if(sym[head1]=='^')
num[head2]=pow(num[head2],num[head2+1]);
head1--;//栈顶符号出栈
}//相应运算
int main()
{
cin>>s;
int i=0;
sym[0]='(';
s+=')';
for(;i<=s.size()-1;)
{
int f=0;
long long x=0;
for(;s[i]<='9'&&s[i]>='0';)
{
x=x*10+s[i]-'0';
i++;
f=1;
}
if(f==1)
num[++head2]=x;//放入数字
if(s[i]=='(')
sym[++head1]=s[i++];//如果是'('直接放入
if(s[i]==')')
{
for(;sym[head1]!='(';)
cumpute();//计算
i++;
head1--;
}
if(s[i]=='+'||s[i]=='-'||s[i]=='*'||s[i]=='/'||s[i]=='^')
{
for(;check(s[i])<=check(sym[head1])&&sym[head1]!='(';)
cumpute();//判断优先级,如果比前面一个优先级低,先进行计算
sym[++head1]=s[i++];//将符号入栈
}
}
for(;head1>=1;)
cumpute();//如果栈中还有符号,继续计算
cout<<num[1]<<endl;
return 0;
}