逆波蘭式(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...