细节有一丢丢小多,具体看注释吧
#include<cstdio>
#include<cstring>
using namespace std;
//先把中缀表达式转成后缀表达式再计算
char s[100010],t[200010];
char sta[100010],top;
inline int calc(char a)//运算符的优先级
{
if(a=='^') return 3;
if(a=='*' || a=='/') return 2;
if(a=='+' || a=='-') return 1;
if(a=='(') return 0;
}
inline int _(int a,int b)//乘方
{
int ret=1;
while(b)
{
if(b&1) ret=ret*a;
b>>=1;a=a*a;
}
return ret;
}
int z[100010];
int main()
{
scanf("%s",s+1);
int len=strlen(s+1),tot=0;
for(int i=1;i<=len;i++)
{
if('0'<=s[i] && s[i]<='9')
{
t[++tot]=s[i];
while('0'<=s[i+1] && s[i+1]<='9') t[++tot]=s[++i];
t[++tot]=' ';//把相邻的两个数断开
continue;
}
if(s[i]=='(') {sta[++top]=s[i];continue;}
if(s[i]==')')
{
while(sta[top]!='(') t[++tot]=sta[top--];
top--;continue;
}
while(calc(sta[top])>=calc(s[i])) t[++tot]=sta[top--];
sta[++top]=s[i];
}
while(top)
{
if(sta[top]!='(') t[++tot]=sta[top--];//去掉多余的括号
else top--;
}
// printf("%s",t+1);
for(int i=1;i<=tot;i++)
{
if('0'<=t[i] && t[i]<='9')
{
int now=0;
while('0'<=t[i] && t[i]<='9') now=now*10+(t[i]^48),i++;
z[++z[0]]=now;
continue;
}
if(z[0]==1) z[z[0]=2]=z[1],z[1]=0;//应对“-1”的奇葩数据
int now;
switch(t[i])
{
case '+':now=z[z[0]-1]+z[z[0]];break;//注意是z[0]-1在前
case '-':now=z[z[0]-1]-z[z[0]];break;
case '*':now=z[z[0]-1]*z[z[0]];break;
case '/':now=z[z[0]-1]/z[z[0]];break;
case '^':now=_(z[z[0]-1],z[z[0]]);break;
}
z[0]-=2;
z[++z[0]]=now;
}
printf("%d\n",z[1]);
return 0;
}