1. 程式人生 > >計算表示式的值(棧)

計算表示式的值(棧)

#題目描述#

小明希望破破一個密碼門。門上有一個算式,其中只有“(”、“)”、“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;
}