定义
- 前缀:不含括号的算术表达式,而且它是将运算符写在前面,操作数写在后面的表达式,也称为“波兰式”。
- 中缀:最常用的算术表达式,运算符在运算数中间,运算需要考虑运算符优先级
- 后缀:是计算机容易运算的表达式,运算符在运算数后面,从左到右进行运算,无需考虑优先级,运算呈线性结构.
例如
中缀 2 + 3 * (7 - 4 )+ 8 / 4
前缀 + + 2 * 3 - 7 4 / 8 4
后缀 2 3 7 4 - * 8 4 / + +
求值
前缀
首先要从右至左扫描表达式,从右边第一个字符开始判断,如果当前字符是数字则一直到数字串的末尾再记录下来,如果是运算符,则将右边离得最近的两个“数字串”作相应的运算,以此作为一个新的“数字串”并记录下来。一直扫描到表达式的最左端时,最后运算的值也就是表达式的值。
用处:它将中缀表达式转换为可以依靠简单的操作就能得到运算结果的表达式,其运算方式为:如果当前字符(或字符串)为数字或变量,则压入栈内;如果是运算符,则将栈顶两个元素弹出栈外并作相应运算,再将结果压入栈内。当前缀表达式扫描结束时,栈里的就是中缀表达式运算的最终结果
中缀
我们正常工作中写的表达式,根据计算符的规则进行运算
后缀 从左到右,遇到运算符就弹出相应的运算数,运算后再把结果入栈.最终结果就是栈顶数的值。有时候’-’(负号)是单目运算符,则要修改运算数。遇到其他运算符(如幂运算)也类似
转换
例如:中缀表达式 2 + 3 * (7 - 4 )+ 8 / 4
中缀转前缀
过程
| 4 | 空 | 4 |
| /4 | / | 4 |
| 8/4 | / | 84 |
| +8/4 | + | /84 |
| )+8/4 | ) + | /84 |
| 4)+8/4 | ) + | 4/84 |
| -4)+8/4 | - ) + | 4/84 |
| 7-4)+8/4 | - )+ | 74/84 |
| (7-4)+8/4 | + | -74/84 |
| *(7-4)+8/4 | * + | -74/84 |
| 3*(7-4)+8/4 | * + | 3-74/84 |
| +3*(7-4)+8/4 | + + | *3-74/84 |
| 2+3*(7-4)+8/4 | + + | 2*3-74/84 |
| 2+3*(7-4)+8/4 | 空 | ++2*3-74/84 |
解析
1、初始化两个栈,符号栈 S1 和结果栈 S2
2、从右至左扫描中缀表达式
3、遇到操作数,直接放到结果栈S2
4、遇到符号数
4.1 如果符号栈为空或者栈顶为 ) ,则直接将运算符入栈S1
4.2 优先级比栈顶运算符高/相等,则运算符入栈S1
4.3 优先级比栈顶运算符低,将S1栈顶运算符压入结果栈S2,然后再与栈S1顶符号对比,循环4.1-4.3
5、遇到括号时
5.1 遇到 ),直接入栈 符号栈S1
5.2 遇到 ( ,从符号栈S1栈顶开始出栈,压入结果栈S2,直到遇到 ) 为止,同时丢弃 ()
6、重复 2 - 5流程,直到表达式最左边
7、将符号栈S1的运算符依次弹出,压入结果栈S2
8、依次弹出结果栈中的元素,即为中缀表达式转为前缀表达式
中缀转后缀
过程
| 2 | 空 | 2 |
| 2+ | + | 2 |
| 2+3 | + | 32 |
| 2+3* | *+ | 32 |
| 2+3*( | (*+ | 32 |
| 2+3*(7 | (*+ | 732 |
| 2+3*(7- | -(*+ | 732 |
| 2+3*(7-4 | -(*+ | 4732 |
| 2+3*(7-4) | *+ | -4732 |
| 2+3*(7-4) | + | *-4732 |
| 2+3*(7-4)+ | ++ | *-4732 |
| 2+3*(7-4)+8 | ++ | 8*-4732 |
| 2+3*(7-4)+8/ | /++ | 8*-4732 |
| 2+3*(7-4)+8/4 | /++ | 48*-4732 |
| 2+3*(7-4)+8/4 | 空 | ++/48*-4732 |
将 ++/48*-4732 依次出栈得到结果 2 3 7 4 - * 8 4 / + +
解析
1、从左到右进行遍历
2、运算数直接入结果栈S2
3、运算符
3.1 运算符是 (,直接入符号栈 S1
3.2 运算符是 ),将符号栈S1 前所有的运算符出栈,入结果栈S2
3.3 运算符非括号,将该运算符和符号栈S1栈顶运算符作比较:高于栈顶运算符,则直接入符号栈S1;
否则,符号栈S1栈顶运算符出栈存入结果栈S2,从符号栈S1弹出元素中直到 遇到更低优先级的元素或者栈为空 为止
4、扫描完成后,符号栈S1中还有运算符时,直接出栈存入结果栈S2
注: 运算符优先级
| 1 | () [] | 从左到右 | |
| 2 | !、~、++、--、+(正号)、-(负号) | 单目运算符 | 从左到右 |
| 3 | *、/、% | 算术运算符 | 从左到右 |
| 4 | +、- | 算术运算符 | 从左到右 |
| 5 | <<、>> | 移位运算符 | 从左到右 |
| 6 | <、<=、>、>= | 关系运算符 | 从左到右 |
| 7 | ==、!= | 关系运算符 | 从左到右 |
| 8 | && | 逻辑运算符 | 从左到右 |
| 9 | \\ | 逻辑运算符 | 从左到右 |
| 10 | ?: | 三目运算符 | 从左到右 |
| 11 | =、+=、 -=、 *=、 /=、%=、 >>=、 <<=、 &=、|=、^= | 赋值运算符 | 从左到右 |