所谓表达式求值就是用计算机计算加减乘除式子,说的装逼一点,就是计算中缀表达式的值。
5 + ((1 + 2) * 4) − 3
我们把这个式子添上括号,保持计算顺序不变。
(
5+((1+2)*4))-3)
运算符夹在数字中间,“中缀”之名由此得来。
人脑可以很快判断计算先后顺序,其实这个过程不是那么显然。因为*/+-有优先级,括号的加入又会打破这个规则。我们可以找出一个式子中最后进行的一步运算,对它的两边分别计算,在根据运算符进行合并。
(5+((1+2)*4))-3)
下面挂的代码是递归实现的。不要骂我标题党,不久会更新真正的栈实现代码,这需要时间,时间~再说递归才符合思维习惯,也更便于记忆~!//表达式求值(递归实现)
/*Author:naeioi
Prog:C++
Time:11.10.22
*/
#include <cstdio>
#include <cstring>
using namespace std;
const int maxl=100;
char s[maxl];
#define isnum(a) (a>='0'&&a<='9')
#define isop(a) (a=='+'||a=='-'||a=='*'||a=='/')
int match(int i)
{
int count=1;
while(count!=0){
i++;
if(s[i]=='(') ++count;
if(s[i]==')') --count;
}
return i;
}
int ston(int p)//下标从p开始
{
int ans=0,positive=1;//符号
if(s[p]=='-'){++p; positive=-1;}
while(isnum(s[p])){
ans*=10;
ans+=s[p++]-'0';
}
return ans*positive;;
}
int div(int l,int r)//求l~r(下标)表示的式子的值
{
while(s[l]=='('&&match(l)==r){++l; --r;}//去除多余括号。不能写成s[l]=='('&&s[r]=')',形如(1+2)*(3+4)的式子会错误
if(l>r) return 0;
int pos,prior=3;//优先级,2==*/,1==+-
for(int i=l;i<=r;i++){//找优先级最小的运算符
if(s[i]=='(')
if((i=match(i)+1)>r)
break;
if(s[i]=='*'||s[i]=='/')
{ if(prior>=2){pos=i; prior=2;}}
else if(s[i]=='+'||s[i]=='-')
if(prior>=1&&i!=l&&!isop(s[i-1])){pos=i; prior=1;}//-接在运算符后时看成符号。否则看成减号
}
if(prior==3)//是一个数
return ston(l);
int a=div(l,pos-1),b=div(pos+1,r),ans;
switch(s[pos])
{
case '+':
ans=a+b;
break;
case '-':
ans=a-b;
break;
case '*':
ans=a*b;
break;
case '/':
ans=a/b;
break;
}
return ans;
}
int main()
{
freopen("eval.in","r",stdin);
freopen("eval.out","w",stdout);
scanf("%s",s);
printf("%d",div(0,strlen(s)-1));
fclose(stdin);
fclose(stdout);
return 0;
}