1. 程式人生 > >波蘭表示法

波蘭表示法

簡化 one 可變 概念 頁面 空格 ati 大量 isp

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的乘積)都完畢時才會處理。在不論什麽表示法中。最裏面的表達式最先運算。而在波蘭表達式中。決定“最裏面”的是順序而不是括號。

簡單算術的前綴表達式主要是用於學術研究方面。與逆波蘭表示法不同,前綴表達式基本沒有在商業計算器中使用過,可是其體系常常在編譯器構造的概念教學中首先使用。

計算機編程

LISP的S-表達式中廣泛地使用了前綴記法,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


波蘭表示法