基於Python的逆波蘭表示式的轉換與求值

2021-09-13 10:46:09 字數 3697 閱讀 3609

逆波蘭式(reverse polish notation,rpn,或逆波蘭記法),也叫字尾表示式(將運算子寫在運算元之後)。而與之對應的是我們在數學中常見的 中綴表示式(既操作符在運算元中間)例如 12+23 就是典型的中綴式,而與之對應的逆波蘭式則為12,13,+

將傳統的中綴式轉化為字尾式後,可以簡化計算機的計算。將複雜表示式轉換為可以依靠簡單的操作得到計算結果的表示式。方便計算機程式設計實現,例如(a+b) * (c+d)轉換為ab+cd+*,就避免了括號的運算,在程式設計和計算上就較少了邏輯判斷與分支的處理。

(一). 逆波蘭式的轉換

首先建立兩個空棧(python中可用list實現棧的功能),stack_expr, stack_opr 分別來裝運算元與操作符。從頭開始遍歷準備好的中綴式,按以下步驟進行轉換: (注:此處本人將中綴式處理為list形式,以方便後續計算,讀者可自行決定中綴式形式 )

附上本人處理後中綴式形式 : 2.0*(3.1+4.8)+5.0  ----> [2.0, '*', '(', 3.1, '+', 4.8, ')', '+', 5.0]

0、當前遍歷到的字元記作index

1、若index是數字, 將該index入棧stack_expr

2、若index是非數字:

2.1、是左括號, 將左括號入棧stack_opr

2.2、是右括號,將stack_opr中的操作符從棧頂依次出棧併入棧stack_expr, 直到遇到左括號終止操作(注意: 該左括號出棧stack_opr但不入棧stack_expr)這樣就消除表示式中的括號消除了

2.3、若index是普通操作符(+ - * /)

2.3.1、 若stack_opr為空, 操作符入棧stack_opr

2.3.2、 如果stack_opr不空,將stack_opr棧頂操作符與index比較優先順序:

2.3.2.1、若index的優先順序高於stack_opr棧頂操作符的優先順序,則index入棧 stack_opr

2.3.2.2、若index的優先順序小於或者等於stack_opr棧頂操作符, stack_opr棧頂操作符出棧併入棧 stack_expr,直到index優先順序高於stack_opr 的優先順序,將index入stack_opr棧。(注:若stack_opr出棧時,將stack_opr出空後,index直接入棧即可)

3、中綴式遍歷結束後如果stack_opr棧不為空,則依次將操作符出棧併入棧stack_expr

**實現:

pat =

['+'

,'-'

,'*'

,'/'

,'('

,')'

,'%'

]def

reverse_polish

(data)

: stack_opr =

list()

#數字棧

stack_expr =

list()

#優先順序

dicts =

global pat

for index in data:

#1.數字,進expr棧

if index not

in pat:

#2.非數字

else

:#2.1 opr棧空

ifnot stack_opr:

#2.2 opr棧非空

else

:#2.2.1 index 是 左括號 ,入棧opr

if index ==

'(':

#2.2.2 index 是右括號,將棧頂的操作符出opr棧,併入expr棧 ,直到遇到左括號

elif index ==

')':

while

true

: newdex = stack_opr.pop(

)#2.2.2.1 newdex是操作符

if newdex !=

'(':

#2.2.2.2 newdex 是左括號

else

:break

#2.2.3 index是普通操作符

else

:while

true

:#2.2.3.0 opr棧空,則直接入棧

ifnot stack_opr:

break

level_index = dicts[index]

level_opr = dicts[stack_opr[-1

]]#2.2.3.1 index 優先順序 比 opr 棧頂優先順序 高 ,index 入 opr棧

if level_index > level_opr:

break

#2.2.3.2 index 優先順序 比 opr 棧頂優先順序 低或等於 , opr棧頂 出棧 並 入expr 棧,直到 index 優先順序 高於 opr 棧頂優先順序

else

: topdex = stack_opr.pop(

)#3. data 原表示式 已被遍歷完,若opr 棧不為空,則依次出棧 進 expr棧

while

true:if

len(stack_opr)!=0

: dex = stack_opr.pop(

)else

:break

return stack_expr

(二). 逆波蘭式的計算

相對於將中綴式轉換為逆波蘭式,逆波蘭式的計算就簡單多了只需如下幾步即可:

建立乙個乙個數值棧stack_res(同樣用list實現),用於存放中間數值以及計算結果

遍歷轉換好的逆波蘭式:

1、如果遇到數字,入棧stack_res;

2、如果遇到運算子, 從stack_res中依次出棧兩個數與 遇到的操作符進行計算即可,將結果壓入stack_res棧中

3、 繼續遍歷下乙個元素,直到結束;

**實現

def

compute

(data)

: stack_res =

list()

global pat

for index in data:

#1 數字,進res棧

if index not

in pat:

#2 運算子

else

:# 2.1 左右運算元

right_ops = stack_res.pop(

) left_ops = stack_res.pop(

)if index ==

'*':

res = left_ops*right_ops

#出數不能為零,需要拋異常進行處理

if index ==

'/':

res = left_ops/right_ops

if right_ops ==0:

raise exception(

'zero'

)if index ==

'+':

res = left_ops+right_ops

if index ==

'-':

res = left_ops-right_ops

iflen

(stack_res)==1

:return stack_res[

0]

波蘭表示式 逆波蘭表示式

中綴表示式是最常見的運算表示式,如 3 5 2 6 1 波蘭表示式又稱為字首表示式,它是由中綴表示式經過一定的方式轉換來的 比如中綴表示式為 3 5x 2 6 1 對應的字首表示式為 3 x 5 2 6 1 對於中綴表示式從右向左遍歷轉換為字首表示式,中途要是用棧進行儲存 轉換規則如下 波蘭表示式 ...

波蘭逆波蘭表示式

實現乙個基本的計算器來計算簡單的表示式字串。表示式字串只包含非負整數,算符 左括號 和右括號 整數除法需要 向下截斷 你可以假定給定的表示式總是有效的。所有的中間結果的範圍為 231,231 1 class solution s2.push s.substr l,r l l r 碰見符號 else ...

波蘭表示式與逆波蘭表示式

2018年09月03日 11 29 15 jitwxs 閱讀數 70 標籤 波蘭 字首 更多 個人分類 演算法與資料結構 常見的算術表示式,稱為中綴表示式,例如 5 6 4 2 3波蘭表示式也稱為字首表示式,以上面的例子為例,其波蘭表示式為 5 6 4 2 3中綴表示式轉換字首表示式的操作過程為 1...