嗯。。。表达式计算的又一道类模板
做这类题,其实就相当于在搞一个大模拟的题目。
我们需要注意的是:因为有多余的括号出现,所以我们最好在一开始把多余的括号去掉,防止中途计算出现问题。
其次,就是需要注意计算的顺序,对于此题,我们应该先算括号,再算乘方,然后按出现顺序算乘除,最后再按出现顺序算加减。
我的代码非常长,因为全程大模拟/xk
不过,其中有很多地方只是稍微改了一点点,应该可读/xk
代码:
#include<bits/stdc++.h> using namespace std; const int N=31; inline int calc(string x){//计算表达式x的值 int sta[N],top=0;int fa[N],val[N],len=x.size(); for(int i=0;i<len;++i){ fa[i]=i;val[i]=0; } //去一层括号 for(int i=0;i<len;++i){ if(x[i]=='('){ sta[++top]=i; }else if(x[i]==')'){ int l=sta[top--]; string y=""; for(int j=l+1;j<i;++j){ y+=x[j]; } int w=calc(y); for(int j=l;j<=i;++j){ fa[j]=l; } val[l]=w; } } //计算数字 for(int i=0;i<len;++i){ if(x[i]>='0'&&x[i]<='9'&&fa[i]==i){ int w=0,r=len-1; for(int j=i;j<len;++j){ if(x[j]<'0'||x[j]>'9'){ r=j-1; break; } w=w*10+(x[j]-'0'); } for(int j=i;j<=r;++j){ fa[j]=i; } val[i]=w; i=r; } } //乘方 for(int i=0;i<len;++i){ if(x[i]=='^'&&fa[i]==i){ int l=0,r=len-1; for(int j=i-1;~j;--j){ if(fa[j]!=fa[i-1]){ l=j+1; break; } } for(int j=i+1;j<len;++j){ if(fa[j]!=fa[i+1]){ r=j-1; break; } } int w=pow(val[fa[l]],val[fa[r]]); for(int j=l;j<=r;++j){ fa[j]=l; } val[l]=w; } } //乘除 for(int i=0;i<len;++i){ if(x[i]=='*'&&fa[i]==i){ int l=0,r=len-1; for(int j=i-1;~j;--j){ if(fa[j]!=fa[i-1]){ l=j+1; break; } } for(int j=i+1;j<len;++j){ if(fa[j]!=fa[i+1]){ r=j-1; break; } } int w=val[fa[l]]*val[fa[r]]; for(int j=l;j<=r;++j){ fa[j]=l; } val[l]=w; } if(x[i]=='/'&&fa[i]==i){ int l=0,r=len-1; for(int j=i-1;~j;--j){ if(fa[j]!=fa[i-1]){ l=j+1; break; } } for(int j=i+1;j<len;++j){ if(fa[j]!=fa[i+1]){ r=j-1; break; } } int w=val[fa[l]]/val[fa[r]]; for(int j=l;j<=r;++j){ fa[j]=l; } val[l]=w; } } //加减 for(int i=0;i<len;++i){ if(x[i]=='+'&&fa[i]==i){ int l=0,r=len-1; for(int j=i-1;~j;--j){ if(fa[j]!=fa[i-1]){ l=j+1; break; } } for(int j=i+1;j<len;++j){ if(fa[j]!=fa[i+1]){ r=j-1; break; } } int w=val[fa[l]]+val[fa[r]]; for(int j=l;j<=r;++j){ fa[j]=l; } val[l]=w; } if(x[i]=='-'&&fa[i]==i){ int l=0,r=len-1; for(int j=i-1;~j;--j){ if(fa[j]!=fa[i-1]){ l=j+1; break; } } for(int j=i+1;j<len;++j){ if(fa[j]!=fa[i+1]){ r=j-1; break; } } int w=val[fa[l]]-val[fa[r]]; for(int j=l;j<=r;++j){ fa[j]=l; } val[l]=w; } } return val[0]; } inline string rebuild(string x){//去掉多余括号 int sta[31],top=0;bool flag[31]; int len=x.size(); for(int i=0;i<len;++i){ if(x[i]=='('){ sta[++top]=i; }else if(x[i]==')'){ if(top)--top; else flag[i]=1; } } for(int i=1;i<=top;++i){ flag[sta[i]]=1; } string y=""; for(int i=0;i<len;++i){ if(!flag[i]){ y+=x[i]; } } return y; } int main(){ string x; cin>>x; printf("%d",calc(rebuild(x))); return 0; }