表达式求值
- 其实仔细想象并不难
- 首先得用栈,我也不知道为什么,可能是因为括号匹配吧
- 对于括号,我们只需要遇到左括号存其来,遇到右括号则计算括号内的值就好了
- 对于二元运算符,运算级相同从左向右计算,运算级不同的先算运算级大的,其实只需要在加入一个运算符之前,把所有优先级大于等于这个运算符的都计算了,就好了
- 对于运算符的计算方式,其实就是维护两个栈,一个数字栈,一个运算符栈。每次运算,取两个数字,计算后,放入数字栈。
- 最后考虑一元运算符,这里wiki说,一元运算符在优先级相同的情况下是从右向左运算的。于是可以所延迟计算,也就是要是一元运算符的话,我们只计算所有优先级严格大于他的运算法即可。
#include <vector>
#include <iostream>
using namespace std;
vector<int> num;
vector<char> opt;
string s; int p = 0;
char get() { if (p == s.size())return 0; return s[p++]; }
int read()
{
int num = 0, c;
while ('0' <= (c = get()) && c <= '9')num = num * 10 + c - '0';
p--; return num;
}
int cal(char c)
{
if (c == '+')return 1;
if (c == '*')return 2;
if (c == '(')return 0;
}
const int mod = 10000;
void solve(char c)
{
int s1, s2, s;
s2 = num.back();num.pop_back();
s1 = num.back();num.pop_back();
if (c == '+')s = (s1 + s2) % mod;
if (c == '*')s = (s1 * s2) % mod;
num.push_back(s);
}
void add(char c)
{
if (c == ')')
{
while (opt.back() != '(')solve(opt.back()), opt.pop_back();
opt.pop_back();return;
}
while (opt.size() && cal(opt.back()) >= cal(c))
solve(opt.back()), opt.pop_back();
opt.push_back(c);
}
int main()
{
cin >> s;s = "(" + s + ")";
while (p != s.size())
{
char c = get();
if ('0' <= c && c <= '9') { p--;num.push_back(read() % mod); }
else add(c);
}
cout << num.back() << '\n';
return 0;
}