表达式树及求值

#include <bits/stdc++.h>
using namespace std;
//从0开始
//另一种方法构建表达式树,并通过表达式树进行表达式求值
//约定表达式都是合法的,且在一行内输入,并没有空格
//约定运算符有 + - * /(整除) ( ) 
//约定操作数都是一位正整数,没有负号
char s[100],ops[100];//ops是树的节点内容
int len=-1,lc[100],rc[100];
//对应节点的左右子树,不想用结构体,伪指针

//思路:运算符优先级最低的点是根
//数值点一定是叶子,单独创建
//最后一个允许的运算符:跳过所有的括号内的运算符,找括号外的 最后一个+-*/,
//如果有-+,就以+-为准,否则以*/为准
int build(int x,int y){
    // [x,y)
    int c1=-1,c2=-1,p=0;
    if(y-x==1){
        //只有一个字符,肯定是数字
        len++;
        ops[len]=s[x];
        rc[len]=lc[len]=-1;
        return len;
    }
    for(int i=x;i<y;i++){
        switch (s[i])
        {
            case '(':p++;break;
            case ')':p--;break;
            //相当于 或
            case '+':case '-':if(!p) c1=i;break;
            case '*':case '/':if(!p) c2=i;break;
        }
    }
    //整体被括号包住了
    //注意在此处停止
    if(c1==-1&&c2==-1) return build(x+1,y-1);
    else if(c1==-1) c1=c2;
    //以+-为准
    int t=++len;//重要,否则递归后len就变了,会赋值错误
    ops[t]=s[c1];
    lc[t]=build(x,c1);//注意左闭右开区间
    rc[t]=build(c1+1,y);
    return t;
}
void zhongxu(int x){
    //因为叶子的左右子树都是0
    if(x==-1) return;
    zhongxu(lc[x]);
    cout<<ops[x];
    zhongxu(rc[x]);
}
int cal(int x){
    if(rc[x]==-1&&lc[x]==-1) return ops[x]-'0';
    int a,b;
    a=cal(lc[x]);
    b=cal(rc[x]);
    switch (ops[x])
    {
        case '+':return a+b;
        case '-':return a-b;
        case '*':return a*b;
        case '/':return a/b;
    }
}
int main()
{   
    cin>>s;
    build(0,strlen(s));
    cout<<cal(0)<<endl;
    return 0;
}

 

posted @ 2020-06-06 21:26  西伯利亚挖土豆  阅读(319)  评论(0编辑  收藏  举报