原题链接
解题思路
源代码
参考算法笔记(胡凡)
#include<iostream>
#include<queue>
#include<stack>
#include<map>
using namespace std;
struct node{
int num; //操作数
char op; //操作符
bool flag; // true为操作数,false为操作符
};
queue<node> q; // 后缀表达式
stack<node> s; // 操作符栈
map<char, int> mp; // 表示操作符的优先级
void change(string str){// 中缀表达式转后缀表达式
node temp;
for(int i=0; i<str.length();){
// 遇到操作符压入栈
if(str[i] >= '0' && str[i] <= '9'){
temp.flag = true;
temp.num = str[i++]-'0';
while(i<str.length() && str[i]>='0' && str[i]<='9'){ // 注意操作数可能不止一位
temp.num = temp.num*10 + (str[i] - '0');
i++;
}
q.push(temp);
}
else{
temp.flag = false;
temp.op = str[i];
if(str[i] == '(') s.push(temp); // 遇到左括号压入栈
else if(str[i] == ')'){
// 遇到右括号就把符号栈中的弹到后缀表达式中直到遇到左括号
node tp;
while(!s.empty()){
tp = s.top();
if(tp.flag==false && tp.op=='('){
s.pop(); // 注意(要弹出去,不进后缀表达式
break;
}
q.push(tp);
s.pop();
}
// 右括号和左括号都不需要出现在后缀表达式中
}
else{
// 只要当前操作符不比栈顶操作符高,就不断将操作符栈中的元素弹到后缀表达式中
while(!s.empty() && mp[str[i]]<=mp[s.top().op]){
q.push(s.top());
s.pop();
}
s.push(temp);
}
i++;
}
}
while(!s.empty()){
q.push(s.top());
s.pop();
}
}
int calc(){ // 计算后缀表达式的值
int temp1, temp2;
node cur, temp;
while(!q.empty()){
cur = q.front();
q.pop();
if(cur.flag) s.push(cur); //操作数直接压入栈
else{
// 如果是操作符
temp2 = s.top().num;
s.pop();
temp1 = s.top().num;
s.pop();
temp.flag = true;
if(cur.op == '+') temp.num = temp1 + temp2;
else if(cur.op == '-') temp.num = temp1 - temp2;
else if(cur.op == '*') temp.num = temp1 *temp2;
else temp.num = temp1 / temp2;
s.push(temp);
}
}
return s.top().num;
}
int main(){
mp['+'] = mp['-'] = 1;
mp['*'] = mp['/'] = 2;
string str;
cin>>str;
while(!s.empty()) s.pop();
change(str);
printf("%d", calc());
return 0;
}