中缀表达式转后缀表达式的方法
- 如果遇到操作数,将其添加到后缀表达式的后面;
- 如果遇到操作符:
- 操作符栈为空时,操作符入栈;
- 遇到左括号时,左括号入栈(无论操作符栈是否为空);
- 遇到右括号时,依次弹出栈中的操作符(添加到后缀表达式中的后面),直到遇到左括号(弹出左括号),左右括号均不添加到后缀表达式中;
- 遇到其他运算符时,依次弹出栈中优先级高于或等于当前操作符高的操作符(添加到后缀表达式后面),或者遇到左括号时停止,然后将当前操作符入栈;
- 将操作符栈中的元素依次弹出(添加到后缀表达式中的后面)。
优先级可视为:* />+ ->(
示例:
中缀表达式1-2*3+(4*(5-6)+7)/8+9 转变为后缀表达式1 2 3 * - 4 5 6 - * 7 + 8 / + 9 +
- 初始状态
- 操作符栈为
[],后缀表达式为""
- 遇到操作数
1,添加到后缀表达式中
- 操作符栈为
[],后缀表达式为"1"
- 遇到操作符
-,此时操作符栈为空,直接入栈
- 操作符栈为
[-],后缀表达式为"1"
- 遇到操作数
2,添加到后缀表达式中
- 操作符栈为
[-],后缀表达式为"1 2"
- 遇到操作符
*,栈中无比*优先级高或相同的操作符,无需弹出,最后将该操作符入栈
- 操作符栈为
[- *],后缀表达式为"1 2"
- 遇到操作数
3,添加到后缀表达式中
- 操作符栈为
[- *],后缀表达式为"1 2 3"
- 遇到操作符
+,弹出栈中比+优先级高或相同的操作符* -添加到后缀表达式中,最后+入栈
- 操作符栈为
[+],后缀表达式为"1 2 3 * -"
- 遇到左括号
(,入栈
- 操作符栈为
[+ (],后缀表达式为"1 2 3 * -"
- 遇到操作数
4,追加到后缀表达式中
- 操作符栈为
[+ (],后缀表达式为"1 2 3 * - 4"
- 遇到操作符
*,弹出栈中优先级高于或等于*的(但栈顶为左括号,无需弹出),最后*入栈
- 操作符栈为
[+ ( *],后缀表达式为"1 2 3 * - 4"
- 遇到左括号
(,左括号入栈
- 操作符栈为
[+ ( * (],后缀表达式为"1 2 3 * - 4"
- 遇到操作数
5,添加到后缀表达式中
- 操作符栈为
[+ ( * (],后缀表达式为"1 2 3 * - 4 5"
- 遇到操作符
-,弹出栈中优先级高于或等于-的(但栈顶为左括号,无需弹出),最后-入栈
- 操作符栈为
[+ ( * ( -],后缀表达式为"1 2 3 * - 4 5"
- 遇到操作数
6,添加到后缀表达式中
- 操作符栈为
[+ ( * ( -],后缀表达式为"1 2 3 * - 4 5 6"
- 遇到右括号
),依次弹出栈中操作符,直到遇到左括号,左右括号均不添加到后缀表达式中
- 操作符栈为
[+ ( *],后缀表达式为"1 2 3 * - 4 5 6 -"
- 遇到操作符
+,弹出栈中优先级高于或等于+的(*),最后+入栈
- 操作符栈为
[+ ( +],后缀表达式为"1 2 3 * - 4 5 6 - *"
- 遇到操作数
7,添加到后缀表达式中
- 操作符栈为
[+ ( +],后缀表达式为"1 2 3 * - 4 5 6 - * 7"
- 遇到右括号
),依次弹出栈中操作符,直到遇到左括号,左右括号均不添加到后缀表达式中
- 操作符栈为
[+],后缀表达式为"1 2 3 * - 4 5 6 - * 7 +"
- 遇到除号
/,弹出栈中优先级高于或等于/的(无),最后/入栈
- 操作符栈为
[+ /],后缀表达式为"1 2 3 * - 4 5 6 - * 7 +"
- 遇到操作数
8,添加到后缀表达式中
- 操作符栈为
[+ /],后缀表达式为"1 2 3 * - 4 5 6 - * 7 + 8"
- 遇到操作符
+,弹出栈中优先级高于或等于+的(/ +),最后+入栈
- 操作符栈为
[+],后缀表达式为"1 2 3 * - 4 5 6 - * 7 + 8 / +"
- 遇到操作数
9,添加到后缀表达式中
- 操作符栈为
[+],后缀表达式为"1 2 3 * - 4 5 6 - * 7 + 8 / + 9"
- 依次弹出栈中剩余元素
- 操作符栈为
[],后缀表达式为"1 2 3 * - 4 5 6 - * 7 + 8 / + 9 +"
结束
class Solution {public:/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可* 返回表达式的值* @param s string字符串 待计算的表达式* @return int整型*/int solve(string s) {// write code herevector<string> infOrder, sufOrder;this->strParser(s, infOrder);printVector(infOrder);this->infill2suffix(infOrder, sufOrder);printVector(sufOrder);return this->suffix2val(sufOrder);}int suffix2val(vector<string>& sufOrder){// 后缀表达式求值stack<int> numStack;int a, b;for(string str : sufOrder){if(isOperator(str)){b = numStack.top();numStack.pop();a = numStack.top();numStack.pop();if(str == "+"){numStack.push(a + b);}else if(str == "-"){numStack.push(a - b);}else if(str == "*"){numStack.push(a * b);}else{numStack.push(a / b);}}else{numStack.push(atoi(str.c_str()));}}return numStack.top();}void infill2suffix(vector<string>& infOrder, vector<string>& sufOrder){// 中缀表达式转后缀表达式sufOrder.clear();stack<string> opStack;for(string str : infOrder){if(isOperator(str)){if(opStack.empty() || str=="("){opStack.push(str);}else if(str == ")"){while(opStack.top() != "("){sufOrder.push_back(opStack.top());opStack.pop();}opStack.pop();}else{while(!opStack.empty() && isHigherOperator(opStack.top(), str)){sufOrder.push_back(opStack.top());opStack.pop();}opStack.push(str);}}else{sufOrder.push_back(str);}}while(!opStack.empty()){sufOrder.push_back(opStack.top());opStack.pop();}}void strParser(string& s, vector<string>& ret){// 解析字符串,将数字和符号分开string curStr = "";for(char ch : s){if(ch >= '0' && ch <= '9'){curStr += ch;}else{if(curStr != ""){ret.push_back(curStr);}ret.push_back(string(1, ch));curStr = "";}}if(curStr != ""){ret.push_back(curStr);}}bool isOperator(string& op){for(int i=0; i<this->ops.size(); i++){if(op == this->ops[i]){return true;}}return false;}bool isHigherOperator(string& op1, string& op2){// 判断op1是否比op2的优先级较高return this->opsPriority[op1] >= this->opsPriority[op2];}private:vector<string> ops={"+", "-", "*", "/", "(", ")"};map<string, int> opsPriority = {{"(", 0},{"+", 1}, {"-", 1},{"*", 2}, {"/", 2}};};
