思路
计算中缀表达式分为两部分:中缀表达式转后缀表达式、后缀表达式的计算。均需要使用栈。
中缀表达式转后缀表达式
inex
:中缀表达式,postex
:后缀表达式,stk
运算符栈- 遍历
inex
- 如果为运算数,则直接添加到
postex
中 - 如果为
(
,则直接入栈stk
- 如果为
)
,一直取出栈顶元素(运算符),直到栈顶运算符为(
为止,取出(
,不将)
入栈 - 如果为
+
、-
、*
、/
运算符,规定为两种优先级。只有目前操作运算符优先级高于栈顶运算符优先级(或者栈空)时才能直接入栈,小于或等于栈顶优先级(注意栈空是直接入栈,所以先处理前者更为简便)需要一直出栈,直至满足当前运算符优先级大于栈顶运算符优先级(或者栈已空),将运算符入栈。出栈的运算符直接添加到postex
中 - 将栈中剩余的运算符依次添加到
postex
中。这样得到的postex
就是后缀表达式。
后缀表达式的计算
- 遍历
postex
- 如果是运算数,则直接入栈
- 如果是运算符,则依次取出两个栈顶元素$$a\b$$,将运算结果$$b xx a$$入栈
- 循环结束,栈中只剩余一个数,该数就是中缀表达式的运算结果
示例代码
#include<bits/stdc++.h>using namespace std;#define ll long long
//#define int ll
#define pii pair<int, int>
#define all(x) x.begin(),x.end()
#define fer(i, m, n) for(int i = m; i < n; ++i)
#define ferd(i, m, n) for(int i = m; i >= n; --i)
#define dbg(x) cout << #x << ' ' << char(61) << ' ' << x << '\n'const int MOD = 1e9 + 7;
const int N = 2e5 + 2;
const int inf = 1e9;// 中缀表达式转后缀表达式
void InexToPostex(string inex, string& postex) {stack<char> stk;map<char, int> mp = {{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};for(char c : inex) {if(c >= '0' && c <= '9') postex += c;else if(c == '(') stk.push(c);else if(c == ')') {while(!stk.empty() && stk.top() != '(') postex += stk.top(), stk.pop();stk.pop();}else if(stk.empty() || mp[c] > mp[stk.top()]) stk.push(c);else if(mp[c] <= mp[stk.top()]) {while(!stk.empty() && mp[c] <= mp[stk.top()])postex += stk.top(), stk.pop();stk.push(c);}}while(!stk.empty()) postex += stk.top(), stk.pop();cout << "postex: " << '\n';for(char c : postex) cout << c << ' ';cout << '\n';
}// 后缀表达式计算
void cal(string postex) {stack<int> stk;for(char c : postex) {if(c >= '0' && c <= '9') stk.push(c - '0');else{int a = stk.top(); stk.pop();int b = stk.top(); stk.pop();if(c == '+') stk.push(a + b);else if(c == '-') stk.push(b - a);else if(c == '*') stk.push(a * b);else if(c == '/') stk.push(b / a);}}cout << "ans: " << stk.top() << '\n';
}signed main() {ios::sync_with_stdio(false); cin.tie(nullptr);string inex, postex;cin >> inex;InexToPostex(inex, postex);cal(postex);return 0;
}
样例输入输出
输入
2*(3+5)+7/1-4
输出
postex:
2 3 5 + * 7 1 / + 4 -
ans: 19