中缀表达式求值
中缀表达式求值
一篇很棒的博客:https://www.acwing.com/solution/content/40978/
思路
使用两个栈,一个操作数栈,一个运算符号栈
将字符串读入
如果字符是操作数就入栈
如果是运算符,就比较它和运算符栈的栈顶元素的优先级。
栈顶符号优先级高,计算(取出操作数栈的栈顶两个数,取出符号栈栈顶元素进行计算,结果push
进栈)
栈顶符号优先级低,push
进栈.
比如: 1 + 2 * 3 + 4 * 5
num栈: 1 2 op 栈: +
遍历到 * ,栈顶(+)的优先级低,* 进栈
num栈: 1 2 3 op 栈: + *
遍历到 + ,栈顶(*)的优先级高,先计算 => 2*3 = 6
num栈: 1 6 op 栈: + +
遍历到 * ,栈顶(+)的优先级低, * 进栈
num栈: 1 6 4 5 op 栈: + + *
一次出栈
(
,)
有些特殊,(
正常入栈,如果遇到)
就从后往前出栈计算直到(
出栈,然后让结果进栈.
加上/
,^
字符一样,考虑其优先级即可
代码模板
摘自acwing模板题https://www.acwing.com/activity/content/problem/content/3648/
#include<iostream>
#include<stack>
#include<cstring>
#include<algorithm>
#include<unordered_map>
using namespace std ;
stack<int> num;
stack<char> op;
void eval()
{
auto b = num.top(); num.pop();
auto a = num.top(); num.pop();
auto 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 if(c == '/') x = a / b;
num.push(x);
}
int main()
{
unordered_map<char,int> pr{{'+',1},{'-',1},{'*',2},{'/',2}};
string str;
cin >> str;
for(int i = 0; i < str.size(); i ++)
{
auto c = str[i];
if(isdigit(c))
{
int x = 0,j = i; // 求出数是多少
while(j < str.size() && isdigit(str[j])) x = x*10 + str[j ++] - '0';
i = j - 1; // 注意回退一个
num.push(x);
}
else if(c == '(') op.push(c);
else if(c == ')') // 如果碰到`)`就从后往前算
{
while(op.top() != '(') eval();
op.pop(); // `(` 出栈
}
else
{
while(op.size() && op.top() != '(' && pr[op.top()] >= pr[c]) eval();
op.push(c);
}
}
while(op.size()) eval();
cout << num.top() << endl;
return 0;
}
rds_blogs