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;
}