一、波兰式(前缀表达式)
波兰式是在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之前,所以,这种表示法也称为前缀表达式。例如:3*(2-(5+1)),用波兰式来表示是:* 3 - 2 + 5 1。
阅读这个表达式需要从左至右读入表达式,如果一个操作符后面跟着两个操作数时,则计算,然后将结果作为操作数替换这个操作符和两个操作数,重复此步骤,直至所有操作符处理完毕。从左往右依次读取,直到遇到+ 5 1,做计算后,将表达式替换为* 3 - 2 6,然后再次从左往右读取,直到遇到- 2 6,做计算后,将表达式替换为*3 (-4)(这里“-”为负号不是减号,-4为一个数负四),从而得到最终结果-12。
二、逆波兰式(后缀表达式)
逆波兰式(Reverse Polish notation,RPN,或逆波兰记法),也叫后缀表达式(将运算符写在操作数之后)。例如:3*(2-(5+1)),用逆波兰式来表示是:3 2 5 1 + - *,也就是把操作运算符往操作数后面放。
阅读这个表达式需要从左往右读入表达式,当读到第一个操作符时,从左边取出两个操作数做计算,然后将这个结果作为操作数替换这个操作符和两个操作数,重复此步骤,直至所有操作符处理完毕。
3 2 5 1 + - *
→3 2 6 - *
→3 (-4) *
→ -12
三、中缀表达式与波兰式、逆波兰式的转换
既然中缀表达式对于计算机的运算并不便利,而前缀后缀表达式的计算相对简单方便。因此,找到一种途径将中缀表达式转换成前缀后缀表达式就十分重要。实际上,二者的转换算法看起来也很像一个逆过程。
相信看完前面写的,大家应该发现了,前缀表达式就是操纵符基本上都分布在操作数的前面,而后缀表达式的操作符又基本上都分布在操作数的后面,那我介绍一种终极简单易懂的转换规律。
同样我们以3*(2-(5+1))举例,当我们在计算中缀表达式的时候,我们只需要把所有优先级用括号标注起来,然后再根据波兰式和逆波兰式,前者把操作符提前,后者提后,再把括号去掉:
3*(2-(5+1))
波兰式 逆波兰式
→(3*(2-(5+1))) → (3*(2-(5+1)))
→(3-(2+(5 1))) → (3(2(5 1)+)-)
→* 3 - 2 + 5 1 → 3 2 5 1 + - *
四、总结
为什么要将看似简单的中序表达式转换为复杂的波兰式或者逆波兰式?原因就在于这个简单是相对人类的思维结构来说的,对计算机而言中序表达式是非常复杂的结构。相对的,逆波兰式在计算机看来却是比较简单易懂的结构。就比如你用用中文说“你是谁”,英语是“Who are you”,直接翻译过来就是”谁是你“,这就是不同的语法规则造成的。所以我们在与计算机交流的时候要用计算机语言。