波兰表示法

http://blog.csdn.net/pipisorry/article/details/37818013

波兰表示法Polish notation。或波兰记法),是一种逻辑算术代数表示方法。其特点是操作符置于操作数的前面。因此也称做前缀表示法。假设操作符的元数(arity)是固定的,则语法上不须要括号仍然能被无歧义地解析。波兰记法是波兰数学家扬·武卡谢维奇1920年代引入的。用于简化命题逻辑

阿隆佐·邱奇在他的经典著作《数理逻辑》中提出该表达方法是一种值得被关注的记法系统,甚至将它与阿弗烈·諾夫·懷海德伯特兰·罗素在《数学原理》中的逻辑表达式相提并论。

[2]

波兰表示法尽管在逻辑领域没有被广泛使用,但仍在计算机科学领域占有一席之地。

算术形式

表达“三加四”时,前缀记法写作“+ 3 4”,而不是“3 + 4”。在复杂的表达式中,操作符仍然在操作数的前面,但操作数可能是包括操作符的平庸表达式。

比如,例如以下的中缀表达式:

(5 ? 6) * 7

写作前缀表示法时是:

*(? 5 6) 7

或省略括号:

* ? 5 6 7

因为简单的算术运算符都是二元的。该前缀表达式无需括号,且表述是无歧义的。在前面的样例里。中缀形式的括号是必需的,假设将括号移动到:

5 ? (6 * 7)

即:

5 ? 6 * 7

则会改变整个表达式的值。

而其正确的前缀形式是:

? 5 * 6 7

减法运算要等它的两个操作数(5;6和7的乘积)都完毕时才会处理。在不论什么表示法中。最里面的表达式最先运算。而在波兰表达式中。决定“最里面”的是顺序而不是括号。

简单算术的前缀表达式主要是用于学术研究方面。与逆波兰表示法不同,前缀表达式基本没有在商业计算器中使用过,可是其体系常常在编译器构造的概念教学中首先使用。

计算机编程

LISPS-表达式中广泛地使用了前缀记法,S-表达式中使用了括号是由于它的算术操作符有可变的元数(arity)。逆波兰表示法在很多基于堆栈程序语言(如PostScript)中使用。以及是一些计算器(特别是惠普)的运算原理。

假定仅仅有二元运算时。操作数的个数必定为操作符的个数加一。否则表达式就无意义。这样在计算更复杂,更长的表达式时。能够简单地忽略某些错误表达式,因此在使用前缀记法时必须小心细致检查其表达意义。

运算顺序

前缀表达式的运算顺序非常easy检測。需注意的是。当运算时,操作符是作用在第一个操作数上。特别是需注意不满足交换律的运算。如除法减法

比如,下列式子:

 / 10 5 = 2  (前缀记法)

表示10/5。结果是2,而不是?。

基于堆栈的操作符由于其本身的特性,无需括号也非常easy区分运算的顺序。因此大量使用波兰记法。

运算波兰表达式时。无需记住运算的层次,仅仅须要直接寻找第一个运算的操作符。以二元运算为例,从左至右读入表达式,遇到一个操作符后尾随两个操作数时。则计算之,然后将结果作为操作数替换这个操作符和两个操作数;反复此步骤,直至全部操作符处理完毕。由于在正确的前缀表达式中。操作数必定比操作符多一个。所以必定能找到一个操作符符合运算条件。而替换时,两个操作数和一个操作符替换为一个操作数。所以降低了各一个操作符和操作数,仍然能够迭代运算直至计算整个式子。

多元运算也类似,遇到足够的操作数即产生运算。迭代直至完毕。迭代结束的条件由表达式的正确性来保证。以下是一个样例。演示了每一步的运算顺序:

 - * / 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
/*求解波兰表达式的值*/
输入数据:
输入为一行,当中运算符和运算数之间都用空格分隔,运算数是浮点数
输出要求:
输出为一行,表达式的值。

* + 11.0 12.0 + 24.0 35.0

编程实现:

/****************************************************************************/
/*	 	POJ读书笔记9.4 —— 波兰表达式2694	皮皮 2014-7-10	*/
/****************************************************************************/
#include <stdio.h>
#include <stdlib.h>

/*	波兰表达式递归算法	*/
double PolNote(){
	char input[10];
	scanf("%s", input);
	switch(input[0]){					//输入字符串字符是否是运算符
	case ‘+‘:
		return PolNote() + PolNote();
	case ‘-‘:
		return PolNote() - PolNote();
	case ‘*‘:
		return PolNote() * PolNote();
	case ‘/‘:
		return PolNote() / PolNote();
	default:
		return atof(input);				//输入字符串数字转换为double
	}
}

int main(){
	printf("%f", PolNote());
	return 0;
}

from:http://blog.csdn.net/pipisorry/article/details/37818013

ref:http://zh.wikipedia.org/zh/%E6%B3%A2%E5%85%B0%E8%A1%A8%E7%A4%BA%E6%B3%95

时间: 2024-11-02 17:58:17

波兰表示法的相关文章

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", "/", "+"]