中缀表达式求值
中缀表达式求值
对于表达式求值,我们通常用栈来操作。
常用的做法是先转换为后缀表达式,再利用栈来求值。
步骤如下:
- 开一个栈一个储存运算符,再开一个结构存后缀表达式,可以选择string数组
- 每遇到一个数字,将其加入到后缀表达式种
- 遇到左括号,加入到符号栈种
- 遇到右括号,不断将栈顶元素添加到后缀表达式中,直到遇到左括号,然后弹出左括号
- 遇到普通运算符,只要栈顶符号的优先级不低于新符号,就不断取出栈顶元素存到后缀表达式,然后将新符号入栈,优先级顺序为
乘除>加减>左括号
- 依次取出符号栈中剩余元素,加入到后缀表达式中
- 将得到的后缀表达式求值
Note
代码在取栈顶元素时容易出错,需要注意对栈为空时的判断
Code
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define mem(a,b) memset(a,b,sizeof(a))
#define debug cout<<0<<endl
#define ll long long
const int MAXN = 1e4 + 10;
const int MOD = 1e9 + 7;
using namespace std;
stack<int> stnumber;
stack<char> stsign;
stack<int> ans;
struct node {
string s="";
} a[MAXN];
int oder(char c) {
if (c == '+' || c == '-') return 1;
else if (c == '*' || c == '/') return 2;
return 0;
}
int toInt(string ss) {
int res = 0;
for (int i = 0; i < ss.length(); i++) {
res = res*10 + ss[i] - '0';
}
return res;
}
int calc(int aa, int bb, char op) {
switch (op) {
case '+':
return aa + bb;
break;
case '/':
return bb / aa;
break;
case '*':
return aa*bb;
break;
case '-':
return bb - aa;
break;
default:
break;
}
}
bool isnum(char si) {
if (si <= '9' && si >= '0') return true;
return false;
}
int cur = 0;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int N;
cin >> N;
string s;
cin >> s;
N = s.length();
int len = 0;
for (int i = 0; i < N; i += len) {
len = 0;
if (isnum(s[i])) {
string t = "";
for (int j = i; j < N; j++) {
if (isnum(s[j])) {
t += s[j];
len++;
} else {
break;
}
}
a[++cur].s = t;
} else {
if (s[i] == '(')
stsign.push(s[i]);
else if (s[i] == ')') {
while (stsign.top() != '(') {
char op = stsign.top();
stsign.pop();
a[++cur].s += op;
}
stsign.pop();
} else {
char op = s[i];
if (!stsign.empty())
while (!stsign.empty() && oder(stsign.top()) >= oder(op)) {
a[++cur].s += stsign.top();
stsign.pop();
//if (stsign.empty()) break;
}
stsign.push(op);
}
len = 1;
}
}
while (!stsign.empty()) {
char op = stsign.top();
stsign.pop();
a[++cur].s += op;
}
// for (int i = 1; i <= cur; i++) {
// cout << a[i].s << endl;
// }
for (int i = 1; i <= cur; i++) {
int temp;
if (isnum(a[i].s[0])) {
temp = toInt(a[i].s);
ans.push(temp);
} else {
int aa = ans.top(); ans.pop();
int bb = ans.top(); ans.pop();
ans.push(calc(aa, bb, a[i].s[0]));
}
}
cout << ans.top();
return 0;
}