表达式求值
时间复杂度O(n)
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
#include <stack>
using namespace std;
stack<char> op;
stack<int> num;
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 x = a / b;
num.push(x);
}
/**
* 定义简单表达式:无括号且操作符递增的表达式为简单表达式,如1 - 2 + 3 * 5 / 6
* 定义复杂表达式: 1)带括号的复杂复杂表达式,如:(1 - 3) * 4
* 2)局部操作符无序,如:1 - 2 + 3 * 4 - 5
* 对于这种算法其实就是一趟运算树的中序遍历,再遍历的过程中括号内的东西在遇到右括号的时候就算完了,
* 然后最终留下的是没有括号的简单的表达式,从而在经过一次后缀表达式的运算就可以了
*
* 该算法保证了,每次操作后的结果都是一个简单表达式,为下次遇到复杂表达式做铺垫,本质上是递归的一个过程,但是转换成了遍历。
**/
int main()
{
string s;
cin >> s;
unordered_map<char, int> pr{{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};
for (int i = 0; i < s.size(); i ++ )
{
if (isdigit(s[i]))//如果是数的话就直接加入数字栈中
{
int j = i, x = 0;
while (j < s.size() && isdigit(s[j]))
x = x * 10 + s[j ++ ] - '0';
num.push(x);
i = j - 1;
}
else if (s[i] == '(') op.push(s[i]);//如果是左括号就加入符号栈中
else if (s[i] == ')')//当遇到右括号就一直操作到左括号,同时此时括号内的表达是已经经过运算的简单表达式,而这步操作也同样是把带括号的复杂表达式简单化
{
while (op.top() != '(') eval();
op.pop();
}
else//这一步处理复杂表达式变为简单表达式比如1 * 2 + 3 -> 2 + 3
{
while (op.size() && op.top() != '(' && pr[op.top()] >= pr[s[i]])
eval();
op.push(s[i]);
}
}
while (op.size()) eval();//最终运算一下处理过后的简单表达式
cout << num.top() << endl;
return 0;
}

浙公网安备 33010602011771号