波兰表示法(前缀表示法)

波兰表示法, 也叫前缀表示法。

运算波兰表达式时,无需记住运算的层次,只需要直接寻找第一个运算的操作符。以二元运算为例,从左至右读入表达式,遇到一个操作符后跟随两个操作数时,则计算之,然后将结果作为操作数替换这个操作符和两个操作数;重复此步骤,直至所有操作符处理完毕。因为在正确的前缀表达式中,操作数必然比操作符多一个,所以必然能找到一个操作符符合运算条件;而替换时,两个操作数和一个操作符替换为一个操作数,所以减少了各一个操作符和操作数,仍然可以迭代运算直至计算整个式子。多元运算也类似,遇到足够的操作数即产生运算,迭代直至完成。迭代结束的条件由表达式的正确性来保证。下面是一个例子,演示了每一步的运算顺序:

其特点是操作符置于操作数的前面,因此也称做前缀表示法。如果操作符的元数(arity)是固定的,则语法上不需要括号仍然能被无歧义地解析

计算方法:

运算波兰表达式时,无需记住运算的层次,只需要直接寻找第一个运算的操作符。以二元运算为例,从左至右读入表达式,遇到一个操作符后跟随两个操作数时,则计算之,然后将结果作为操作数替换这个操作符和两个操作数;重复此步骤,直至所有操作符处理完毕。因为在正确的前缀表达式中,操作数必然比操作符多一个,所以必然能找到一个操作符符合运算条件;而替换时,两个操作数和一个操作符替换为一个操作数,所以减少了各一个操作符和操作数,仍然可以迭代运算直至计算整个式子。多元运算也类似,遇到足够的操作数即产生运算,迭代直至完成。迭代结束的条件由表达式的正确性来保证。下面是一个例子,演示了每一步的运算顺序:

− × ÷ 15 − 7 + 1 1 3 + 2 + 1 1 =

− × ÷ 15 − 7 2     3 + 2 + 1 1 =

− × ÷ 15 5         3 + 2 + 1 1 =

− × 3              3 + 2 + 1 1 =

− 9                  + 2 + 1 1 =

− 9                  + 2 2     =

− 9                  4         =

5

等价的中缀表达式:  ((15 ÷ (7 − (1 + 1))) × 3) − (2 + (1 + 1)) = 5

下面的伪代码用一个stack求prefix的值 。注意和上面的从左到右处理的算法不同,是从右往左扫描 , 但两个算法计算出来的值相同。(其实这个算法相当于后续遍历时候先遍历右子树)

Scan the given prefix expression from right to left

for each symbol

{

if operand then

push onto stack

if operator then

{

operand1=pop stack

operand2=pop stack

compute operand1 operator operand2

push result onto stack

}

}

return top of stack as result

Applying this algorithm to the example above yields the following:

− × ÷ 15 − 7 + 1 1 3 + 2 + 1 1 =

− × ÷ 15 − 7 + 1 1 3 + 2 2     =

− × ÷ 15 − 7 + 1 1 3 4         =

− × ÷ 15 − 7 2     3 4         =

− × ÷ 15 5         3 4         =

− × 3              3 4         =

− 9                  4         =

5

This uses the same expression as before and the algorithm above.

− × ÷ 15 − 7 + 1 1 3 + 2 + 1 1


Token


Action


Stack


Notes


1


Operand


1


Push onto stack.


1


Operand


1 1


Push onto stack.


+


Operator


2


Pop the two operands (1, 1), calculate (1 + 1 = 2) and push onto stack.


2


Operand


2 2


Push onto stack.


+


Operator


4


Pop the two operands (2, 2), calculate (2 + 2 = 4) and push onto stack.


3


Operand


3 4


Push onto stack.


1


Operand


1 3 4


Push onto stack.


1


Operand


1 1 3 4


Push onto stack.


+


Operator


2 3 4


Pop the two operands (1, 1), calculate (1 + 1 = 2) and push onto stack.


7


Operand


7 2 3 4


Push onto stack.



Operator


5 3 4


Pop the two operands (7, 2), calculate (7 − 2 = 5) and push onto stack.


15


Operand


15 5 3 4


Push onto stack.


÷


Operator


3 3 4


Pop the two operands (15, 5), calculate (15 ÷ 5 = 3) and push onto stack.


×


Operator


9 4


Pop the two operands (3, 3), calculate (3 × 3 = 9) and push onto stack.



Operator


5


Pop the two operands (9, 4), calculate (9 − 4 = 5) and push onto stack.

The result is at the top of the stack.

参考:

http://en.wikipedia.org/wiki/Polish_notation 及其中文链接

时间: 2024-11-06 17:26:28

波兰表示法(前缀表示法)的相关文章

波兰表示法

http://blog.csdn.net/pipisorry/article/details/37818013 波兰表示法(Polish notation.或波兰记法),是一种逻辑.算术和代数表示方法.其特点是操作符置于操作数的前面.因此也称做前缀表示法.假设操作符的元数(arity)是固定的,则语法上不须要括号仍然能被无歧义地解析.波兰记法是波兰数学家扬·武卡谢维奇1920年代引入的.用于简化命题逻辑. 阿隆佐·邱奇在他的经典著作<数理逻辑>中提出该表达方法是一种值得被关注的记法系统,甚至将

leetcode-计算逆波兰表示法的值

package edu.bupt.cici.leetcode; import java.util.ArrayList; public class EvaluateReversePolishNotation { public int evalRPN(String[] tokens) { int temp = 0; int length = tokens.length; ArrayList<Integer> stack = new ArrayList<Integer>(); for (

逆波兰表示法

逆波兰表示发是一种将运算符写在操作数后面的描述程序(算式)的方法.举个例子,我们平常用中缀表示法描述的算式(1 + 2) * (5 + 4),改为逆波兰表示法之后则是1 2 + 5 4 + *.相较于中缀表示法,逆波兰表示法的优势在于不需要括号. 请输出以逆波兰表示法输入的算式的计算结果. 输入   在1行中输入1个算式.相邻的符号(操作数或运算符)用1个空格隔开. 输出   在1行之中输出计算结果. 限制   2≤算式中操作数的总数≤100 1≤算式中运算符的总数≤99 运算符仅包括"+&qu

栈的应用----四则运算,后缀逆波兰表示法(RPN)

我们从小就学习四则运算--加减乘除四则.我们也知道,要先乘除后加减,遇到括号要先算括号内的.可是,想让计算机进行这样的四则运算可不容易,它可不知道什么乘除优先,然后加减.那么,该如何让计算机也能进行这样的四则运算呢?就是通过栈. 我们人类非常熟悉也非常喜欢用中缀表示法进行算数运算,什么是中缀表示法呢?也就是,一个运算符在两个数字中间.比如,5+3,3*5,5/2等等,这些都是中缀表示法.这种表示法很适合人类使用,但是却不适用于计算机,于是,我们就想出了一种适合计算机的表示方式,叫做,后缀表示法,

逆波兰法(计算器)程序&lt;无符号版&gt;

涉及队列.栈的运用. Java中队列可以用: Queue<String> q = new LinkedList(); 来声明,其主要的方法有: poll(),peak(),offer(),clear(),size()等. Java中栈可以用: Stack s = new Stack(); 来声明,其主要方法有:push(),peak(),pop(),clear(),size()等. 1 package preTest; 2 3 import java.util.LinkedList; 4 im

逆波兰法求解数学表达示(C++)

主要是栈的应用,里面有两个函数deleteSpace(),stringToDouble()在我另一篇博客当中:对string的一些扩展函数. 本程序只是基本的功能实现,没有差错控制. #include<iostream> #include<stack> #include<string> #include<map> #include"fstring.h" /* *采用逆波兰表示法求解数学表达示 *1.将输入的中缀表示示转换成后缀表达示 *2

逆波兰表达式

1696:逆波兰表达式 总时间限制: 1000ms 内存限制: 65536kB 描述 逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3.逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 + 3) * 4的逆波兰表示法为* + 2 3 4.本题求解逆波兰表达式的值,其中运算符包括+ - * /四个. 输入 输入为一行,其中运算符和运算数之间都用空格分隔,运算数是浮点数. 输出 输出为一行,表达式的值.可直接用prin

中缀输入逆波兰计算器程序part1

在看K&R的时候,里面提到了逆波兰表示法,老实说看得我迷迷糊糊的,主要是这种反人类的后缀表示法做出的计算器,一般人根本就不知道怎么输入好吧.今天看书的时候,看到了将中缀表达式转为后缀表达式的方法才恍然大悟,原来是少了这一步.这下我就知道该如何做一个可用的逆波兰计算器了. 先简单介绍一下如何完成这步转换吧.中缀表达式就是我们习惯的表达式,比如:1+2*3 考虑运算符优先级的话后缀表达式则应该写成123*+ 写成后缀表达式的形式后我们可以利用栈轻松地解决计算问题,思路是当见到一个数时就把它推入栈:在

lintcode 中等题:Evaluate Reverse Polish notation逆波兰表达式求值

题目 逆波兰表达式求值 在逆波兰表达法中,其有效的运算符号包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰计数表达. 样例 ["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9 ["4", "13", "5", "/", "+"]