• 表达树求值


    找到最后处理的运算符,它是整个树的根,然后递归处理。

    注意:下面代码不能处理 -1这样的表达式。

     

    #include <iostream>
    #include <cstring>
    using namespace std;
    const int MAXN = 1000;
    int lch[MAXN],rch[MAXN]; //每个结点的左右儿子
    char op[MAXN];    //存放每个结点的字符
    char input[MAXN]; //input数组存放输入的表达式字符串
    int nc = 0;    //nc存放表达式树的结点,开始时结点数为0
    
    /*****************************************************
      递归构造表达式树,每次找括号外的+、-、*、/
      优先+、-划分,其次*、/划分,原则是找最后运算的符号
      如果所有运算符均在括号内,忽略这个括号,继续递归内层
    *****************************************************/
    int buildTree(char *s,int x,int y) { //根据表达式建立表达式树
        //c1、c2分别记录“最右”出现的加减号和乘除号
        //标志p=0避免记录括号内的+、-、*、/
        int i,c1 = -1, c2 = -1, p = 0; 
        int u;
        if(y-x == 1) { //仅一个字符,建立单独结点
            u = nc++;
            lch[u] = rch[u] = 0; //单独结点无左右子树,所以左右子树的编号为0
            op[u] = s[x];   //此时把s[x]值赋给数组op[u]
            return u;
        }
        for(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 < 0)  c1=c2; //找不到括号外的加减号,就用乘除号
        if(c1 < 0)  return buildTree(s, x+1, y-1); //整个表达式被一对括号括起来
        u = nc++;
        //对结点的左子树区间[x,c1],对表达式进行处理
        lch[u] = buildTree(s,x,c1); 
        //对结点的右子树区间[c1+1,y],对表达式进行处理
        rch[u] = buildTree(s,c1+1,y); 
        op[u] = s[c1];  //
        return u;
    }
    
    int transTree(int cur) { //根据算术表达式树,来计算表达式值
        //当前结点无左右子树,op[cur]-'0'表示一个数值
        if(lch[cur] ==0 || rch[cur] == 0) 
            return op[cur] - '0';   
        else {
            int ret1 = transTree(lch[cur]); //计算当前结点左子树的值
            int ret2 = transTree(rch[cur]); //计算当前结点右子树的值
            switch(op[cur])
            {   //根据当前结点是+、-、*、/,由左右子树值计算当前结点的值
                case '+':
                    return ret1 + ret2; 
                case '-':
                    return ret1 - ret2;
                case '*':
                    return ret1 * ret2;
                case '/':
                    return ret1 / ret2;
            }
        }
    }
    
    /*********************************
      输入算术表达式:a+b*(c-d)-e/f
      输出算术表达式的运算结果
    *********************************/
    int main() {
        memset(input, 0, sizeof(input)); //初始化数组input
        cin >> input;  //从键盘输入的字符串存放在数组input中
        buildTree(input, 0, strlen(input)); //建立表达式树
        cout << transTree(0) << endl;   //计算表达式的值    
        return 0;
    }
  • 相关阅读:
    vue.js环境配置步骤及npm run dev报错解决方案
    消息处理之performSelector
    iOS开发网络篇—发送GET和POST请求(使用NSURLSession)
    iOS手机号正则表达式并实现344格式 (正则的另一种实现方式)
    IOS开发——正则表达式验证手机号、密码
    iOS网络请求之---GET和POST
    CLLocation
    ios本地文件内容读取,.json .plist 文件读写
    UITableViewCell的4种样式
    iOS开发通过代码方式使用AutoLayout (NSLayoutConstraint + Masonry)
  • 原文地址:https://www.cnblogs.com/cute/p/3964884.html
Copyright © 2020-2023  润新知