不简单啊。。。
描述
中缀表达式求值
解析
#include <iostream>
#include <string>
#include <stack>
#include <unordered_map>
using namespace std;
unordered_map<char, char> mp = {{'(', ')'}, {'[', ']'}, {'{', '}'}};
int getans(string str) {
int length = str.size();
stack<int> st;
int number = 0;
char opr = '+';
int i = 0;
int now;
while (i < length) {
char ch = str[i];
if (mp.count(ch)) {
char target = mp[ch];
++i;
int begin = i;
int cnt = 1;
while (i < length) {
if (str[i] == target) {
if (--cnt == 0) break;
} else if (str[i] == ch) ++cnt;
++i;
}
number = getans(str.substr(begin, i - begin));
} else if (isdigit(ch)) {
number = number * 10 + ch - '0';
} else {
switch (opr) {
case '+':
st.push(number);
break;
case '-':
st.push(-1 * number);
break;
case '*':
now = st.top();
st.pop();
st.push(now * number);
break;
case '/':
now = st.top();
st.pop();
st.push(now / number);
break;
}
opr = ch;
number = 0;
}
++i;
}
switch (opr) {
case '+':
st.push(number);
break;
case '-':
st.push(-1 * number);
break;
case '*':
now = st.top();
st.pop();
st.push(now * number);
break;
case '/':
now = st.top();
st.pop();
st.push(now / number);
break;
}
int ans = 0;
while (!st.empty()) {
ans += st.top();
st.pop();
}
return ans;
}
int main() {
string str;
cin >> str;
cout << getans(str);
return 0;
}
整体思路
unordered_map<char, char> mp = {{'(', ')'}, {'[', ']'}, {'{', '}'}};
int getans(string str) {
int length = str.size();
stack<int> st;
int number = 0;
char opr = '+'; // 前一个符号
int i = 0;
while (i < length) {
char ch = str[i];
if (mp.count(ch)) {
// 细节1:括号内递归
} else if (isdigit(ch)) {
number = number * 10 + ch - '0';
} else {
// 细节2:运算符计算并更新
}
++i;
}
// 细节3: 最后一个运算符计算
// stack所有元素求和
}
细节1 括号递归
注意多个括号嵌套的情况(1+(1+2)*3)
,不能是匹配到反括号)
就结束,那样就会出现1+(1+2)
导致逻辑错误。
需要一个cnt计数,遇到第一个括号ch相同则++,遇到与第一个括号匹配的反括号则--,cnt为0则匹配完成。
char target = mp[ch];
++i;
int begin = i;
int cnt = 1;
while (i < length) {
if (str[i] == target) {
if (--cnt == 0) break;
} else if (str[i] == ch) ++cnt;
++i;
}
number = getans(str.substr(begin, i - begin));
细节2&&细节3 运算符计算并更新
opr
实际是上一个符号,默认为'+'。
上一个符号:表达式(1*1)
可被理解为+1*1
,类似的-1*2
通过这种转换,即栈里边为 0,-1
实现了负数的判别。
因此,循环结束还有最后一个符号没处理,需要在循环之外处理,这就是细节3