一、后缀(逆波兰)表示法
小学的时候我们就学过数学运算的规则:先乘除后加减,从左算到右,先括号内后括号外。对于9 + (3 - 1) × 3 + 10 ÷ 2这样一个表达式,我们很快就知道结果是20。但是在计算机内部,是如何计算的呢?
20世纪50年代,波兰逻辑学家Jan Łukasiewicz想到了一种不需要括号的后缀表示法,我们称之为逆波兰表示(Reverse Polish Notation, RPN),非常巧妙地解决了程序实现四则运算的难题。
对于表达式9 + (3 - 1) × 3 + 10 ÷ 2,如果用后缀表示法是这个样子的:9 3 1-3 × + 10 2 ÷ +,这样的表达式称为后缀表达式,叫后缀的原因在于所有的符号都是在要运算的数字的后面出现。
二、后缀表达式的计算
我们来看看计算机是如何应用后缀表达式计算出结果的。
规则:从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,是符号就将处于栈顶的两个数字出栈进行运算,然后将运算结果进栈,一直到获取到最终结果。
1、初始化一个空栈,用来对要运算的数字进出使用,如下左图。
2、后缀表达式的前三个都是数字,因此9、3、1进栈,如下右图:
3、接下来是-,所以将栈中的1出栈作为减数,3出栈作为被减数,并将运算结果2进栈。
4、接下来是数字3进栈。
5、后面是×,所以栈中3和2出栈并相乘,将结果6入栈。
6、下面是+,所以栈中6和9出栈相加,将结果15入栈。
7、接着是10和2进栈。
8、接下来是符号÷,栈顶的2与10出栈,10与2相除,得到5,将5进栈。
9、最后一个是符号+,所以5与15出栈并相加,得到结果20,20进栈。
10、结果是20出栈,栈为空。
那么,后缀表达式是如何的来的呢?
三、中缀表达式转后缀表达式
我们平时使用的标准四则运算表达式叫做中缀表达式,因为所有的运算符都在两个数字的中间,现在的问题就是将中缀表达式转为后缀表达式。
规则:从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,称为后缀表达式的一部分;若是符号,则判断其与栈顶符号的优先级,是右括号或优先级不高于栈顶符号则栈顶元素依次出栈并输出,并将当前符号进栈,一直到最终输出后缀表达式为止。
1、初始化一个空栈,用来对符号进出栈使用。
2、第一个字符是9,输出9,后面是符号+,进栈。
3、第三个符号是(,因其是左括号,所以入栈。
4、第四个符号是数字3,输出。接着是-,进栈。
5、接下来是数字1,输出。后面是符号),此时,我们需要去匹配前面的(,所以,栈顶元素依次出栈并输出,直到(出栈为止。此时(上方只有-,因此输出-。
6、紧接着是符号×,因为此时栈顶符号是+,优先级低于×,因此×进栈。接着是数字3,输出。
7、之后是符号+,此时当前栈顶元素的×比+优先级高,因此栈中元素出栈并输出。由于没有比+更低的优先级,所以全部出栈。然后再将这个+入栈。此时,前面几张图中的+是中缀表达式开头的9后面那个+,而下图左图中的+是指刚刚入栈的+,即9 + (3 - 1) × 3 +中后面的一个+。
8、紧接着是数字10,输出。后是符号÷,进栈。
9、最后一个数字2,输出。
10、因已到最后,因此将栈中符号全部出栈并输出,最终输出的后缀表达式是9 3 1-3 × + 10 2 ÷ +。
因此,要让计算机能处理通常的标准(中缀)表达式的能力,关键就是两步:
1、将中缀表达式转为后缀表达式(栈用来进出运算符号)
2、将后缀表达式进行运算得出结果(栈用来进出运算的数字)