中缀表达式转后缀表达式的方法
- 如果遇到操作数,将其添加到后缀表达式的后面;
- 如果遇到操作符:
- 操作符栈为空时,操作符入栈;
- 遇到左括号时,左括号入栈(无论操作符栈是否为空);
- 遇到右括号时,依次弹出栈中的操作符(添加到后缀表达式中的后面),直到遇到左括号(弹出左括号),左右括号均不添加到后缀表达式中;
- 遇到其他运算符时,依次弹出栈中优先级高于或等于当前操作符高的操作符(添加到后缀表达式后面),或者遇到左括号时停止,然后将当前操作符入栈;
- 将操作符栈中的元素依次弹出(添加到后缀表达式中的后面)。
优先级可视为:* /
>+ -
>(
示例:
中缀表达式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 here
vector<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}
};
};