分析
1、中缀表达式,中序遍历树
树的所有内部节点是运算符,叶子节点是数字
2、
如何判断某棵子树被遍历完
往上走,说明数被遍历完,往下走,说明没有被遍历完,
加入运算符后,
往上走等价于当前运算符优先级低于上一个运算符的优先级,
3、用栈来存数字和运算符,用哈希表来表示优先级,
代码实现
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <stack>
#include <unordered_map>
using namespace std;
//1、先定义两个栈,一个存数,一个存运算符,
//并且定义哈希表,用关键字表示运算符优先级
stack<int> num;
stack<int> op;
unordered_map<char , int> pr{
{'+' , 1},{'-' , 1},{'*' , 2},{'/' , 2}
};
//7、操作两个相邻的数a*b
void eval()
{
int b = num.top() ; num.pop();
int a = num.top() ; num.pop();
int c = op.top() ; op.pop();
int x;
if(c == '+') x = a+b;
else if(c == '-') x = a-b;
else if(c == '*') x = a*b;
else x = a/b;
num.push(x);
}
int main()
{
string str;
cin>>str;
//2、枚举每个字符,对每个字符进行处理
for ( int i = 0 ; i<str.size() ; i++ )
{
int c = str[i];
//3、如果为数字字符,就压到数栈里
if( isdigit(c) )
{
int x = 0 , j = i;//往后扫描所有连着的字符数字
while( j < str.size() && isdigit(str[j]) )
x = x * 10 + str[j++] - '0';//换成int数字
i = j - 1;//更新i
num.push(x);
}
else if( c == '(' ) op.push(c);
else if( c == ')' )
{
//4、如果遇见右括号,就从右括号开始,从右往左计算,直至栈顶遇见左括号
while( op.top() != '(') eval();
op.pop();
}
else
{
//5、遇见其它运算符,比较优先级,当,当前运算符优先级小于等于
//上一个运算符的优先级,即往上走表明该节点的所有子树已经遍历完了,
while( op.size() && pr[ op.top() ]>=pr[c] ) eval();
op.push(c);//将新进来的压入
}
}
//6、遍历剩余的运算符
while( op.size() ) eval();
cout<<num.top()<<endl;
}