算术表达式
前/中/后缀表达式
- 前缀表达式(波兰式):操作符在操作数的前面,比如
+-543
; - 中缀表达式:操作符在操作数的中间,这也是人类最容易识别的算术表达式
3+4-5
; - 后缀表达式(逆波兰式):操作符在操作数的后面,比如
34+5-
。
前缀表达式的计算机求值
从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素 op 次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果。
例如前缀表达式- × + 3 4 5 6
:
- 从右至左扫描,将 6、5、4、3 压入堆栈;
- 遇到
+
运算符,因此弹出 3 和 4(3 为栈顶元素,4 为次顶元素,注意与后缀表达式做比较),计算出 3 + 4 的值,得 7,再将 7 入栈; - 接下来是
×
运算符,因此弹出 7 和 5,计算出 7 × 5 = 35,将 35 入栈; - 最后是-运算符,计算出 35 - 6 的值,即 29,由此得出最终结果。
中缀表达式转后缀表达式
- 初始化两个栈:运算符栈 S1 和储存中间结果的栈 S2;
- 从左至右扫描中缀表达式;
- 遇到操作数时,将其压入 S2;
- 遇到运算符时,比较其与 S1 栈顶运算符的优先级;
- 如果 S1 为空,或栈顶运算符为左括号
(
,则直接将此运算符入栈 S1; - 若优先级比栈顶运算符的高,也将运算符压入S1(注意必须高于,相同和低于都不行);
- 否则,将 S1 栈顶的运算符弹出并压入到 S2 中,再次转到
4.a
。
- 如果 S1 为空,或栈顶运算符为左括号
- 遇到括号时:
- 如果是左括号
(
,则直接压入 S1; - 如果是右括号
)
,则依次弹出 S1 栈顶的运算符,并压入 S2,直到遇到左括号位置,然后将这一对括号丢弃。
- 如果是左括号
- 重复步骤
2
到5
,直到来到表达式的最右边; - 将 S1 中剩余的运算符依次弹出并压入 S2;
- 依次弹出 S2 中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式。
中缀表达式转前缀表达式
- 首先构造一个运算符栈,然后从右至左扫描中缀表达式。
- 如果是操作数,则直接输出,作为前缀表达式的一个直接转换表达式Temp(最后,前缀表达式由该表达式翻转得到);
- 如果是运算符,则比较优先级:若该运算符优先级大于等于栈顶元素,则将该运算符入栈,否则栈内元素出栈并加到Temp表达式尾端,直到该运算符大于等于栈顶元素的优先级时,再将该运算符压入栈中。
- 遇到右括号直接压入栈中,
- 如果遇到一个左括号,那么就将栈元素弹出并加到Temp表达式尾端,但左右括号并不输出。
- 最后,若运算符栈中还有元素,则将元素一次弹出并加到Temp表达式尾端,最后一步是将Temp表达式翻转。