2 jmu-ds-二叉树实现表达式求解

2 jmu-ds-二叉树实现表达式求解 (50 分)

用二叉树来表示表达式,树的每一个节点包括一个运算符和运算数。代数表达式中只包含+-*/和一位整数且没有错误。按照先括号,再乘除,后加减的规则构造二叉树。如图所示是"1+(2+3)*2-4/5"代数表达式对应二叉树,用对应的二叉树计算表达式的值。

输入格式:

输入一行表达式字符串,括号内只能有一个运算符。

输出格式:

输出表达式的计算结果.如果除数为0,提示divide 0 error!

输入样例1:

(1+2)*3-4/5+(3-2)

结尾无空行

输出样例1:

9.2

结尾无空行

输入样例2:

1+2*3-4

输出样例2:

3

#include <iostream>
#include <string>
#include <stack>
#include <unordered_map>

using namespace std;

stack<char> op;            //运算符栈 
stack<double> num;         //运算数栈 
unordered_map<char, double> pr = {{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};   //建立哈希表判断运算优先级 

void eval()                     //进行表达式计算 
{
    double b = num.top(); num.pop();
    double a = num.top(); num.pop();         //从运算数栈中取出两个数 
    char c = op.top(); op.pop();             //从运算符栈中取出一个运算符 

    double x;
    if(c == '+') x = a + b;                  //计算 
    if(c == '-') x = a - b;
    if(c == '*') x = a * b;
    if(c == '/') 
    {
        if(b!=0) x = a / b;
        if(b==0) 
        {
            cout<<"divide 0 error!";
            exit(0);
        }
    }

    num.push(x);                          //将计算结果再次压入运算数栈中 
}

int main()
{
    string s;
    cin >> s;

    for(int i = 0; i < s.size(); i++)
    {
        char c = s[i];
        if(isdigit(c))
            num.push(c-'0');             //如果是数字就把它压入运算数栈 
        else if(c == '(') op.push(c);    //如果是左括号,把左括号压入运算符栈中 
        else if(c == ')')                //如果是右括号,需要从左到右进行计算 
        {
            while(op.size() && op.top() != '(') eval();      //如果运算符栈顶不是左括号且栈不为空,就需要进行一次计算 
            op.pop();            //弹出左括号 
        }
        else
        {
            while(op.size() && pr[op.top()] >= pr[c]) 
			    eval();   //如果是运算符,且当前运算符小于等于栈顶运算符优先级 ,需要进行一次计算 
            op.push(c);   //把当前运算符压入栈中 
        }
    }
    while(op.size()) eval();    //直到运算符全部计算完 
    cout << num.top() << endl;  //输入运算数栈中最终的数据 

    return 0;
}

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值