(1)不使用eval()等系統自帶的計算方法
(2)實現四則混合運算、括號優先級解析
思路:
1、字符串預處理,將所有空格去除
2、判斷是否存在括號運算,若存在進行第3步,若不存在則直接進入第4步
3、利用正則表達式獲取最底層括號內的四則運算表達式
4、將四則運算表達式進行預處理:表達式開頭有負數時,在表達式前加上一個0
5、利用re.split()、re.findall()方法,通過加減符號,對四則運算進行拆分為乘除運算式和數字,并保留對應的位置下標。
6、利用re.split()、re.findall()方法,通過乘除符號,將乘除式拆分為乘除符號與數字,然后進行計算,并返回數值。
7、通過re.split()、re.findall()保留的下標位置,將表達式還原。
8、完成所有乘除運算之后,返回進行加減運算。
9、完成加減運算后,返回表達式進行替代。
10、通過遞歸函數,完成所有括號運算后。最后再完成一次四則運算即可完成所有運算。
注:在過程中,負數的處理存在三個要點:當負數出現在表達式開頭、負數前面存在減法、乘除式中存在負數且不在表達式開頭。
(1)當負數出現在表達式開頭:在前面加上一個0
(2)負數前面存在減法:每次完成一次運算后需要進行一次符號檢查替換
(3)乘除式中存在負數且不在表達式開頭:將負號移到表達式最開頭
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
#!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Dang import re def update_formula(calc_list,calc_operator_list): # 通過拆分后的表達式列表與符號列表重新組合 for index,item in enumerate (calc_list): if index = = 0 : formula = item elif index ! = 0 : formula + = calc_operator_list[index - 1 ] + item return formula def negative_start_issue(formula): #處理負數在括號內表達式開頭的情形 calc_list = re.split( "[+-]" ,formula) #通過+-符號將各個乘除運算分隔出來 calc_operator_list = re.findall( "[+-]" ,formula) for index,item in enumerate (calc_list): if index = = 0 and item = = '': # 處理負號在開頭的問題 calc_list[index] = '0' else : calc_list[index] = item.strip() formula = update_formula(calc_list,calc_operator_list) return formula def deal_unusual_issue(formula): # 雙加減符號處理 formula = formula.replace( " " ,"") #去掉空格 formula = formula.replace( "++" , "+" ) formula = formula.replace( "+-" , "-" ) formula = formula.replace( "-+" , "-" ) formula = formula.replace( "--" , "+" ) return formula def deal_negative_issue(formula): # 處理乘除運算中負數的計算問題(分前后位置兩種情況) # 1.負數在后 m = re.search( "[0-9]+[.]*[0-9]*[*|/][-][0-9]+[.]*[0-9]*" ,formula) # minus_pre = re.search("[0-9]+[.]*[0-9]*[*|/][-][0-9]+[.]*[0-9]*",formula).group() # 注意匹配的必要項與非必要項,如:"[0-9]+[.][0-9]+[*|/][-][0-9]+[.][0-9]+"誤把非必要項當做必要項。 if m: minus_pre = m.group() minus_pro = "-" + minus_pre.replace( "-" ,"") formula = formula.replace(minus_pre,minus_pro) if "*-" in formula or "/-" in formula: return deal_negative_issue(formula) # 2.負數在前 formula = deal_unusual_issue(formula) return formula def multiply_divide(formula): # print("[%s]"%formula,formula) # 乘除計算 calc_list = re.split( "[*/]" , formula) operator_list = re.findall( "[*/]" , formula) # 將乘號除號通過列表方式分隔出來 # print("sub_calc_list:", sub_calc_list) # print("sub_operator_list:", sub_operator_list) res = 0 for index2, i in enumerate (calc_list): if index2 = = 0 : res = float (i) else : if operator_list[index2 - 1 ] = = '*' : # 通過sub_operator_list中的index判斷到底是加法還是減法, res * = float (i) elif operator_list[index2 - 1 ] = = '/' : res / = float (i) return res def add_abstract(formula): # 加減計算 # 1.開頭位置負數處理 formula = negative_start_issue(formula) # 2.雙加減符號處理 formula = deal_unusual_issue(formula) # 3.加減邏輯運算 calc_list = re.split( "[+-]" , formula) operator_list = re.findall( "[+-]" , formula) res = 0 for index, i in enumerate (calc_list): if index = = 0 : res = float (i) else : if operator_list[index - 1 ] = = '+' : res + = float (i) elif operator_list[index - 1 ] = = '-' : res - = float (i) return res """ |
四則混合運算主函數
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
"""def elementary_arithmetic(formula): # 負數處理 formula = negative_start_issue(formula) formula = deal_negative_issue(formula) # 乘除運算 calc_list = re.split("[+-]",formula) # 通過+-符號將各個乘除運算分隔出來 calc_operator_list = re.findall("[+-]",formula) for index1, item in enumerate(calc_list): calc_list[index1] = str(multiply_divide(item)) #數據類型的強制轉換!!! formula = update_formula(calc_list,calc_operator_list) # 加減運算 formula = add_abstract(formula) return formula """ 括號運算 """ def calculator(formula): #數據預處理 formula = formula.replace( " " ,"") m = re.search( "\([^()]*\)" ,formula) # 判斷是否需要進行括號運算 if m: # 括號運算 # 提取最小括號運算式,計算結果,并返回。 subformula = m.group().strip( "()" ) # 把找出來的括號剝離 print ( "subformula:" ,subformula, type (subformula)) subres = elementary_arithmetic(subformula) # 調用四則混合運算主函數 print ( "subres:" ,subres) formula = formula.replace(m.group(), str (subres)) print ( "updated formula:" ,formula) if "(" in formula: return calculator(formula) else : print ( "formula result:" ,formula) # 除去所有括號后可能出現:1-2*-312.8 formula = elementary_arithmetic(formula) return formula else : return elementary_arithmetic(formula) # 以下為測試代碼: formula = "1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*9/4*28 +10 * 56/14 )) - (-4*3)/ (16-3*2) )" print ( "%s = " % formula,calculator(formula)) |
總結
以上所述是小編給大家介紹的Python利用正則表達式實現計算器算法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!
原文鏈接:https://www.cnblogs.com/yimengtianya1/archive/2018/04/25/8945762.html