中缀表达式转换为后缀表达式的算法通常采用“逆波兰表达式转换法”,具体步骤如下:
- 初始化两个栈:
一个操作符栈
operatorStack
一个输出栈
outputStack
(可以用列表或字符串模拟)
如果是操作数(数字或变量),直接放到
outputStack
里。如果是左括号
(
,也放到operatorStack
里。如果是右括号
)
,则从operatorStack
里弹出元素,直到遇到左括号为止,把这些弹出的元素都放到outputStack
里,但左括号本身不放入outputStack
。如果是运算符(比如
+
,-
,*
,/
),则需要考虑运算符的优先级:如果
operatorStack
为空,或者栈顶是左括号(
,直接把当前运算符压入栈。否则,比较当前运算符和栈顶运算符的优先级,如果当前运算符优先级低,就把栈顶的运算符弹出并放入
outputStack
,然后继续比较;如果当前运算符优先级高或者相等(考虑右结合性),就把当前运算符压入栈。
- 如果遍历完表达式后,
operatorStack
里还有运算符,就依次弹出并放到outputStack
里,直到operatorStack
为空。
示例
以中缀表达式3+4*2/(1-5)
为例,转换成后缀表达式的过程如下:
- 初始化两个栈:
operatorStack=[]
outputStack=[]
3
是操作数,直接放到outputStack
:+
是运算符,压入operatorStack
:[+]
4
是操作数,直接放到outputStack
:[3,4]*
是运算符,压入operatorStack
:[+,*]
2
是操作数,直接放到outputStack
:[3,4,2]/
是运算符,压入operatorStack
:[+,*,/]
(
是左括号,压入operatorStack
:[+,*,/,(]
1
是操作数,直接放到outputStack
:[3,4,2,1]-
是运算符,压入operatorStack
:[+,*,/,(,-]
5
是操作数,直接放到outputStack
:[3,4,2,1,5])
是右括号,从operatorStack
弹出元素并放到outputStack
,直到遇到左括号:弹出
-
并放到outputStack
:[3,4,2,1,5,-]弹出
*
并放到outputStack
:[3,4,2,1,5,-,*]弹出
/
并放到outputStack
:[3,4,2,1,5,-,*,/])
是右括号,从operatorStack
弹出元素并放到outputStack
,直到遇到左括号:弹出
(
并忽略
operatorStack
为空,直接将operatorStack
中的运算符依次弹出并放到outputStack
:弹出
+
并放到outputStack
:[3,4,2,1,5,-,*,/,+]
3+4*2/(1-5)
转换成后缀表达式为34215-*/+
。