表达树求值

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

注意:下面代码不能处理 -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;
}
时间: 2024-11-06 14:49:31

表达树求值的相关文章

【数算A】表达式&#183;表达式树&#183;表达式求值

这道题在输出上太坑了,画出来不像树... 1 #include<iostream> 2 #include<cstring> 3 #include<stack> 4 using namespace std; 5 int val[26],n,len,ans,maxDep; 6 char infix[55],postfix[55],out[50][300]; 7 struct node{ 8 int ch; 9 node *l,*r; 10 node(){ 11 l=r=NU

杭电 1754 I Hate It(线段树求最值)

http://acm.hdu.edu.cn/showproblem.php?pid=1754 I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 38601    Accepted Submission(s): 15270 Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某

2016年湖南省第十二届大学生计算机程序设计竞赛---Parenthesis(线段树求区间最值)

原题链接 http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1809 Description Bobo has a balanced parenthesis sequence P=p1 p2…pn of length n and q questions. The i-th question is whether P remains balanced after pai and pbi  swapped. Note that questions ar

poj 2763 树链剖分(单点更新,区间求值)

http://poj.org/problem?id=2763 Description After their royal wedding, Jiajia and Wind hid away in XX Village, to enjoy their ordinary happy life. People in XX Village lived in beautiful huts. There are some pairs of huts connected by bidirectional ro

POJ - 2155 Matrix (二维树状数组 + 区间改动 + 单点求值 或者 二维线段树 + 区间更新 + 单点求值)

POJ - 2155 Matrix Time Limit: 3000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u Submit Status Description Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row and j-th column. Initially we ha

权值线段树求逆序对问题

我们都知道,求逆序对数量可以用归并排序解决.但是用归并排序只能解决静态的序列问题,没有扩展的区间.因此就有了用权值线段树求逆序对的方法. 1 #include<iostream> 2 #include<iomanip> 3 #include<ctime> 4 #include<climits> 5 #include<algorithm> 6 #include<queue> 7 #include<vector> 8 #inc

hdu3966 树链剖分(区间更新和单点求值)

http://acm.hdu.edu.cn/showproblem.php?pid=3966 Problem Description Our protagonist is the handsome human prince Aragorn comes from The Lord of the Rings. One day Aragorn finds a lot of enemies who want to invade his kingdom. As Aragorn knows, the ene

hdu 2665 可持久化线段树求区间第K大值(函数式线段树||主席树)

http://acm.hdu.edu.cn/showproblem.php?pid=2665 Problem Description Give you a sequence and ask you the kth big number of a inteval. Input The first line is the number of the test cases. For each test case, the first line contain two integer n and m (

light oj 1348 树链剖分(单点更新区间求值)

http://lightoj.com/volume_showproblem.php?problem=1348 Finally the Great Magical Lamp was in Aladdin's hand. Now he wanted to return home. But he didn't want to take any help from the Genie because he thought that it might be another adventure for hi