四則運算的解析

2022-03-04 14:28:17 字數 3597 閱讀 6602

怎樣將字串的算數表示式計算出來?

如果使用正規表示式來匹配,有點不怎麼好想,而且一般想法設計到遞迴,而在python中是非常不建議使用遞迴的,

因為它不僅有遞迴深度的限制(一般是1000個棧幀),而且不支援尾遞迴優化。

最簡單的辦法就是先將表示式轉化為字首表示式,然後通過字首表示式來計算出結果。

字首表示式(運算子在前面)也被稱為波蘭式,相應的字尾表示式(運算子在後面)也被成為逆波蘭式,而我們生活中,還有

常見的大多數程式語言中使用的都是中綴表示式。

中綴表示式轉化為字首表示式規則:

(1) 初始化兩個棧:運算子棧s1和儲存中間結果的棧s2;

(2) 從右至左掃瞄中綴表示式

(3) 遇到運算元時,將其壓入s2

(4) 遇到運算子時,比較其與s1棧頂運算子的優先順序:

(4-1) 如果s1為空,或棧頂運算子為右括號「)」,則直接將此運算子入棧

(4-2) 否則,若優先順序比棧頂運算子的較高或相等,也將運算子壓入s1

(4-3) 否則,將s1棧頂的運算子彈出並壓入到s2中,

再次轉到(4-1)與s1中新的棧頂運算子相比較

(5) 遇到括號時:

(5-1) 如果是右括號「)」,則直接壓入s1

(5-2) 如果是左括號「(」,則依次彈出s1棧頂的運算子,並壓入s2,直到遇到右括號為止,

此時將這一對括號丟棄

(6) 重複步驟(2)至(5),直到表示式的最左邊

(7) 將s1中剩餘的運算子依次彈出並壓入s2

(8) 依次彈出s2中的元素並輸出,結果即為中綴表示式對應的字首表示式。

使用字首表示式來計算最大特點就是它去掉了括號。

將中綴表示式轉化為字首表示式

def

mid_to_prev(expressions: str):

priority =

expression_list =expressions.split() #

number_stack = # 數字棧

symbol_stack =# 運算子棧

for x in expression_list[::-1]:

ifx.isdigit():

number_stack.insert(0, x) # 如果是整數直接存進去 如果想要判斷是否是數字 可以使用 float函式 並且 加上 try except

else

:

if x == '('

: # 如果是 ( 彈出運算子棧中的運算子直到遇到 (

pop_symbol =symbol_stack[0]

while pop_symbol != ')'

: pop_symbol =symbol_stack.pop(0)

number_stack.insert(0, pop_symbol)

pop_symbol =symbol_stack[0]

else

: symbol_stack.pop(0)

elif len(symbol_stack) == 0 or symbol_stack[0] == ')'

or x == ')'

or priority[x] >=priority[symbol_stack[0]]:

symbol_stack.insert(0, x) # 當符號棧為空 或者 遇到 ) 或者棧頂的符號是 ) 或者優先順序大於等於符號棧頂的運算子優先順序 直接存進去

elif priority[x] < priority[symbol_stack[0]]: #

優先順序小於符號棧頂元素的時候

while symbol_stack[0] != ')'

and priority[x]

number_stack.insert(0, symbol_stack.pop(0))

else

: symbol_stack.insert(0, x)

else

:

while len(symbol_stack) !=0:

number_stack.insert(0, symbol_stack.pop(0))

return number_stack

例子:

將轉化到的字首表示式進行運算就簡單了

(1)初始化乙個新列表

(2)從右往左遍歷字首表示式列表,遇到數字,存到新列表中

(3)遇到運算子,就彈出新列表中的前兩個數字,進行運算,再將結果儲存到新列表中

(4)直到新列表中遍歷完字首表示式列表,此時新列表中就只有乙個元素,就是最終的結果

def calc(number1,number2,calc): #

兩個數運算

if calc == '/'

:

return number1 /number2

elif calc == '*'

:

return number1 *number2

elif calc == '//'

:

return number1 //number2

elif calc == '**'

:

return number1 **number2

elif calc == '%'

:

return number1 %number2

elif calc == '+'

:

return number1 +number2

elif calc == '-'

:

return number1 - number2

得到總的結果:

def

operation(stack_list:list):

number =

for x in stack_list[::-1]:

ifx.isdigit():

number.insert(0, x)

else

: first =number.pop(0)

second =number.pop(0)

tmp =calc(int(first),int(second), x)

number.insert(0,tmp)

return number.pop(0)

例項:前面的字首表示式結果:

經驗證結果是正確的。

注:表示式要用空格分隔,因為 // 和 ** 如果正常切割的話,會變成兩個字元

只是對整數進行了匹配

python四則運算程式 四則運算(Python)

四則運算程式 一 資訊 二.題目要求 寫乙個能自動生成小學四則運算題目的程式,然後在此基礎上擴充套件 除了整數以外,還要支援真分數的四則運算,例如 1 6 1 8 7 24 程式要求能處理使用者的輸入,判斷對錯,累積分數 程式支援可以由使用者自行選擇加 減 乘 除運算 三 import random...

java四則運算

public class arithmetic implements serializable 除法 param number1 除數 param number2 被除數 param decimal 保留幾位小數點 return public static double divide string ...

C 四則運算

一 問題及 檔名稱 兩個浮點數的四則運算 02.作 者 李欽 03.完成日期 2016 年 3 月 12 日 04.版 本 號 v1.0 05.對任務及求解方法的描述部分 06.輸入描述 07.問題描述 略 08.程式輸出 略 09.問題分析 略 10.演算法設計 略 11.includevoid ...