栈-表达式求值

栈-表达式求值

   所谓表达式求值就是用计算机计算加减乘除式子,说的装逼一点,就是计算中缀表达式的值。
    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;
}

你可能感兴趣的:(栈-表达式求值)