逆波兰表示的应用
2015-12-13 21:55
232 查看
逆波兰表达式又叫做后缀表达式。在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,这种表示法也称为中缀表示。波兰逻辑学家J.Lukasiewicz于1929年提出了另一种表示表达式的方法,按此方法,每一运算符都置于其运算对象之后,故称为后缀表示。
逆波兰表达式最常应用的场景是用于四则运算表达式的求值,其实逆波兰表达也就是栈的一种应用,逆波兰表达式是一种新的显示方式,非常巧妙地解决了程序实现四则运算的难题。
下面我们看一个例子:计算9+(3-1)* 3 + 10/2的值。
如果使用逆波兰表达式就可以轻松解决这个问题了。通过上面的运算表达式转化为逆波兰表达式可以得到的式子为:9 3 1 - 3 * + 10 2 / +,
那么逆波兰表达式是如何计算结果的呢,要知道它是如何进行计算首先的要知道它的计算规则:从左到右遍历表达式的每一个数字和符号,遇到是数字就进栈,遇到是符号,就将处于栈顶两个数字出栈,进行运算,运算结果进栈,一直最终获得结果。
它的计算步骤为:
1、初始化一个空栈,此栈用来对运算的数字进出使用。
2、逆波兰表达式中的前三个数字都是数字,所以9、3、1进栈。
3、接下来是“-” ,所以讲栈中的1出栈作为减数,3出栈作为被减数,运算得到2,再将2进栈。
4、接着是数字3进栈。
5、后面是“*”,也就意味着栈中3和2出栈,2与3相乘,得到6,并将6进栈。
6、下面是“+”,所以栈中6和9出栈,9与6相加,得到15,将15出栈。
7、接着是10与2两个数字进栈。
8、接下来是符号“/”,因此,栈顶的2与10出栈,10与2相除,得到5,将5出栈。
9、最后一个符号“+”,所以15与5出栈并相加,得到20,将20进栈。
10、结果是20出栈,栈变为空,计算完成。
通过上面的步骤,我们发现逆波兰表达式果然可以和顺利的解决计算的问题。那么新的问题又来了,我们是怎么得到根据表达式得到逆波兰表达式的呢,只有解决了这个问题我们才能彻底的明白逆波兰的使用。
我们把平常所用的标准四则运算表达式,即:“9+(3-1)*
3 + 10/2”叫做中辍表达式,因为所有的运算符号都是在连个数字中间。
那么我们也必须知道它们的规则:从左到右遍历中辍表达式的每个数字和符号,若是数字就输出,即成为逆波兰表达式的一部分;若是符号,则判断其与栈顶符号的优先级,是右括号或者优先级高于栈顶符号(乘除优先于加减)则栈顶元素依次出栈并输出,并将当前符号进栈,直到最终输出逆波兰表达式为止。
步骤为:
1、初始化一个空栈,用来对符号进出栈使用。
2、第一个字符是数字,输出9,后面是符号“+”,进栈。
3,、第三个字符是“(”,依然是符号,因其只是左括号,还没配对,故进栈。
4、第四个字符是数字3,输出,此时总表达式为9 3 ,接着是“-”,进栈。
5、接下来是数字1,输出,总表达式为9 3 1 ,后面符号是“)”,此时,我们需要去匹配此前的“(”,所以栈顶依次出栈并输出,直到“(”出栈为止。此时左括号上方只有“-”,因此输出“-”。总表达式为9
3 1 - 。
6、紧接着是符号“*”,因为此时的栈顶符号为“+”号,优先级低于“*”,因此不输出,“*”进栈。接着是数字3,输出,总的表达式为9
3 1 - 3 。
7、之后是符号“+”,此时当前的栈顶元素“*”比这个“+”的优先级高,因此栈中元素出栈并输出(没有比“+”号更低的优先级,所以全部出栈),总输出表达式9
3 1 - 3 * + 。然后将当前这个符号“+”进栈。
8、紧接着数字10 ,输出,总表达式为9 3 1 - 3 * + 10、后面符号“/”,所以“/”进栈。
9、最后一个数字2,输出,总的表达式为9 3 1 - 3 * + 10
2 。
10、因已经到了最后,所以将栈中符号全部出栈并输出。最终输出的逆波兰表达式为:9
3 1 - 3 * 10 2 / + 。
经上面的推导中我们发现,想要让计算机更具有处理我们通常的标准(中缀)表达式的能力,最重要就是两步:
1、将中缀醉话逆波兰表达式(栈用来进出运算的符号)
2、将逆波兰表达式进行运算的出结果(栈用来运算进出运算的数字)
逆波兰表达式最常应用的场景是用于四则运算表达式的求值,其实逆波兰表达也就是栈的一种应用,逆波兰表达式是一种新的显示方式,非常巧妙地解决了程序实现四则运算的难题。
下面我们看一个例子:计算9+(3-1)* 3 + 10/2的值。
如果使用逆波兰表达式就可以轻松解决这个问题了。通过上面的运算表达式转化为逆波兰表达式可以得到的式子为:9 3 1 - 3 * + 10 2 / +,
那么逆波兰表达式是如何计算结果的呢,要知道它是如何进行计算首先的要知道它的计算规则:从左到右遍历表达式的每一个数字和符号,遇到是数字就进栈,遇到是符号,就将处于栈顶两个数字出栈,进行运算,运算结果进栈,一直最终获得结果。
它的计算步骤为:
1、初始化一个空栈,此栈用来对运算的数字进出使用。
2、逆波兰表达式中的前三个数字都是数字,所以9、3、1进栈。
3、接下来是“-” ,所以讲栈中的1出栈作为减数,3出栈作为被减数,运算得到2,再将2进栈。
4、接着是数字3进栈。
5、后面是“*”,也就意味着栈中3和2出栈,2与3相乘,得到6,并将6进栈。
6、下面是“+”,所以栈中6和9出栈,9与6相加,得到15,将15出栈。
7、接着是10与2两个数字进栈。
8、接下来是符号“/”,因此,栈顶的2与10出栈,10与2相除,得到5,将5出栈。
9、最后一个符号“+”,所以15与5出栈并相加,得到20,将20进栈。
10、结果是20出栈,栈变为空,计算完成。
通过上面的步骤,我们发现逆波兰表达式果然可以和顺利的解决计算的问题。那么新的问题又来了,我们是怎么得到根据表达式得到逆波兰表达式的呢,只有解决了这个问题我们才能彻底的明白逆波兰的使用。
我们把平常所用的标准四则运算表达式,即:“9+(3-1)*
3 + 10/2”叫做中辍表达式,因为所有的运算符号都是在连个数字中间。
那么我们也必须知道它们的规则:从左到右遍历中辍表达式的每个数字和符号,若是数字就输出,即成为逆波兰表达式的一部分;若是符号,则判断其与栈顶符号的优先级,是右括号或者优先级高于栈顶符号(乘除优先于加减)则栈顶元素依次出栈并输出,并将当前符号进栈,直到最终输出逆波兰表达式为止。
步骤为:
1、初始化一个空栈,用来对符号进出栈使用。
2、第一个字符是数字,输出9,后面是符号“+”,进栈。
3,、第三个字符是“(”,依然是符号,因其只是左括号,还没配对,故进栈。
4、第四个字符是数字3,输出,此时总表达式为9 3 ,接着是“-”,进栈。
5、接下来是数字1,输出,总表达式为9 3 1 ,后面符号是“)”,此时,我们需要去匹配此前的“(”,所以栈顶依次出栈并输出,直到“(”出栈为止。此时左括号上方只有“-”,因此输出“-”。总表达式为9
3 1 - 。
6、紧接着是符号“*”,因为此时的栈顶符号为“+”号,优先级低于“*”,因此不输出,“*”进栈。接着是数字3,输出,总的表达式为9
3 1 - 3 。
7、之后是符号“+”,此时当前的栈顶元素“*”比这个“+”的优先级高,因此栈中元素出栈并输出(没有比“+”号更低的优先级,所以全部出栈),总输出表达式9
3 1 - 3 * + 。然后将当前这个符号“+”进栈。
8、紧接着数字10 ,输出,总表达式为9 3 1 - 3 * + 10、后面符号“/”,所以“/”进栈。
9、最后一个数字2,输出,总的表达式为9 3 1 - 3 * + 10
2 。
10、因已经到了最后,所以将栈中符号全部出栈并输出。最终输出的逆波兰表达式为:9
3 1 - 3 * 10 2 / + 。
经上面的推导中我们发现,想要让计算机更具有处理我们通常的标准(中缀)表达式的能力,最重要就是两步:
1、将中缀醉话逆波兰表达式(栈用来进出运算的符号)
2、将逆波兰表达式进行运算的出结果(栈用来运算进出运算的数字)
相关文章推荐
- 创建二叉排序树并查找值为x的节点(c语言版)
- tomcat+nginx
- 如何按内容筛选dom
- js正则整合
- LDA perplexity计算
- HDU 2553 N皇后问题 --- 经典回溯
- 为sproto手写了一个python parser
- Python 提高效率
- CUDA学习——BMP文件格式
- jQuery中prop()和attr()方法的测试和总结
- 更新证书错误:No matching provisioning profiles found
- 小谈深度优先搜索
- 带头节点链表和不带头节点链表的初始化
- shell变量
- CUDA学习--一维矩阵的加
- Nginx配置文件详细说明
- 《失落的世纪致富经典》卷二:1致富就是遵照“既定的法则”做事
- Objective-C内存管理第五弹:自动释放池
- leetcode -- Subsets I &II-- 重点,求0,1序列
- 字节序、比特序(二)----结构体的传输