表达式求值
前言
我们平时见到的表达式一般为中缀表达式,比如3 + 5 * (2 - 1)
,这个表达式对于计算机来说并不是直接计算出它的答案的,而是先将其转换成后缀表达式然后再进行计算。
后缀表达式(逆波兰表达式)
举个例子,计算一个中缀表达式的具体步骤:
- 中缀表达式:
3 + 5 * (2 - 1)
- 转换为后缀表达式:
3 5 2 1 - * +
- 计算结果
转换过程
转换的步骤通常遵循运算符优先级和括号规则以及左优先原则:
- 操作数:遇到操作数(数字)时,将其放入输出列表。
- 操作符:遇到操作符时,根据优先级进行处理:
- 如果当前操作符的优先级高于栈顶操作符,则将其压入栈。
- 如果当前操作符的优先级低于或等于栈顶操作符,则将栈顶操作符弹出,加入输出列表,直到找到优先级较低的操作符或栈为空,然后将当前操作符压入栈。
- 括号:
- 遇到左括号 ( 时,将其压入栈。
- 遇到右括号 ) 时,将栈中的操作符弹出并加入输出列表,直到遇到左括号。
以3 + 5 * (2 - 1)
为例:
- 栈->
[]
,输出->[]
- 栈->
[]
,输出->[3]
- 栈->
[+]
,输出->[3]
- 栈->
[+]
,输出->[3, 5]
- 栈->
[+, *]
,输出->[3, 5]
- 栈->
[+, *, (]
,输出->[3, 5]
- 栈->
[+, *, (]
,输出->[3, 5, 2]
- 栈->
[+, *, (, -]
,输出->[3, 5, 2, 1]
- 栈->
[+, *]
,输出->[3, 5, 2, 1, -,]
- 栈->
[+]
,输出->[3, 5, 2, 1, -, *]
- 栈->
[]
,输出->[3, 5, 2, 1, -, *, +]
最后得到结果:3 5 2 1 - * +
计算过程
- 遇到操作数时,将其压入栈。
- 遇到操作符时,从栈中弹出相应数量的操作数进行运算,并将结果压回栈。
- 最终,栈中剩下的值就是表达式的结果。
以后缀表达式3 5 2 1 - * +
为例:
- 栈->
[]
- 栈->
[3]
- 栈->
[3, 5]
- 栈->
[3, 5, 2]
- 栈->
[3, 5, 2, 1]
- 栈->
[3, 5, 1]
- 栈->
[3, 5]
- 栈->
[8]
最后得到结果:8
前缀表达式(波兰表达式)
前缀表达式是将操作符放到了两个操作数前面,比如:
中缀表达式3 + 5 * (2 - 1)
转换为后缀表达式为+ 3 * 5 - 2 1
它的转换规则与逆波兰表达式基本一致,只是遍历方向变成了从右往左。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 AnA.!
评论