我前兩年有次在一家做網路安全的公司筆試就遇到這道題:「輸入字串的四則運算,返回計算結果」,我當時絞盡腦汁也沒想到怎麼做,後來直接跟hr說我可能不適合這個崗位就走了,不是因為我做不出這道題才放棄,而是因為試卷上考了很多網路安全的問題,xx注入,xx攻擊之類的我一臉懵逼所以放棄。回到正題,我當時對這道題印象很深,一直都想要說有空寫一下這道題,最近才花時間完成了順便記錄一下。
這道題經典的解法是轉成逆波蘭表示式再計算(字尾表示式),最大好處是可以去掉括號,定義如下(摘自龍書):
關鍵問題是怎麼轉成字尾表示式,後來又大概知道了用兩個棧實現,再結合定義,只知道了這兩點直接手擼**了,沒抄也沒看過網上或其他人的任何**
# s1存放字尾表示式的結果,入到棧1的字元是已經完成表示式轉換的部分,s2存放那些待計算的運算子,棧頂元素就是當前要正在被處理的運算子,棧底就是最後被處理的運算子
priority_dict =
defcal
(str1)
: now_op =
''for s in str1:
if s.isdigit():
s1.push(s)
s2.push(now_op)
elif s ==
'(':
s2.push(now_op)
s2.push(s)
now_op =
''elif s ==
')':
# 如果遇到反括號,則需要一直出棧遇到括號,也就是清空當前括號內的運算子,完成運算
while s2.top()!=
'(':
t = s2.pop(
) s1.push(t)
s2.pop(
) now_op = s2.top(
)if s2.top()!=
'('else
''else
:# 如果遇到新的運算子需要對當前運算子做相應處理
if priority_dict[s]
< priority_dict[now_op]
:# 如果新的優先順序比當前優先順序低,則要把之前括號內的運算子都入到棧1,也就完成處理
while
not s2.isempty(
)and s2.top()!=
'('and priority_dict[s2.top()]
>= priority_dict[s]
: s1.push(s2.pop())
elif priority_dict[s]
== priority_dict[now_op]
:# 如果優先順序一樣,則把上次運算子入棧1
ifnot s2.isempty():
s1.push(s2.pop())
now_op = s
s2.stackprint(
)while
not s2.isempty():
t = s2.pop(
) s1.push(t)
波蘭表示式 逆波蘭表示式
中綴表示式是最常見的運算表示式,如 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...