嗯。。。表达式计算的又一道类模板
做这类题,其实就相当于在搞一个大模拟的题目。
我们需要注意的是:因为有多余的括号出现,所以我们最好在一开始把多余的括号去掉,防止中途计算出现问题。
其次,就是需要注意计算的顺序,对于此题,我们应该先算括号,再算乘方,然后按出现顺序算乘除,最后再按出现顺序算加减。
我的代码非常长,因为全程大模拟/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;
} 
京公网安备 11010502036488号