最终计算器需求:
- 实现加减乘除及拓号优先级解析
- 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式,运算后得出结果,结果必须与真实的计算器所得出的结果一致。
a+b
1 1 # 1.用于计算 a+b 的计算式。其中 a 和 b 是整数或者有限小数。没有空格和括号。没有其他四则计算。 2 2 3 3 import re 4 4 5 5 def addtion(): 6 6 formula = input("请输入一个公式(严格按照a+b)格式:") # 得到一个公式字符串 7 7 num_list = re.split("+",formula) # 这里要注意,加号为元字符,前要加转义字符才行。结果得到一个列表 [a,b] 8 8 return float(num_list[0]) + float(num_list[1]) # num_list[0] = "a" 是个字符。需要转成 float 类型 9 9 print(addtion())
a-b
1 # 2.用于计算 a-b 的计算式。其中 a 和 b 是整数或者有限小数。没有空格和括号。没有其他四则计算。 2 3 import re 4 5 def addtion(): 6 formula = input("请输入一个公式(严格按照a-b)格式:") # 得到一个公式字符串 7 num_list = re.split("-",formula) # 这里要注意,减号不是元字符。结果得到一个列表 [a,b] 8 return float(num_list[0]) - float(num_list[1]) # num_list[0] = "a" 是个字符。需要转成 float 类型 9 print(addtion())
a+b 或 a-b
1 # 3.用于计算 a-b 或者 a+b 的计算式。其中 a 和 b 是整数或者有限小数。没有空格和括号。没有其他四则计算。 2 3 import re 4 5 def addtion(): 6 formula = input("请输入一个公式(严格按照a+b或a-b)格式:") # 得到一个公式字符串 7 symbol = re.search("[-+]",formula).group() # 此处serach得到的是个对象,需要调用group()方法,得到一个字符串。 8 num_list = re.split("[-+]",formula) # 不需要使用转义符号 9 if symbol == "-": 10 return float(num_list[0]) - float(num_list[1]) # num_list[0] = "a" 是个字符。需要转成 float 类型 11 12 else: 13 return float(num_list[0]) + float(num_list[1]) # num_list[0] = "a" 是个字符。需要转成 float 类型 14 print(addtion())
多位数加减(可带空格和 - 符号)比如 - 3 + 4 - 2
1 def symbol_result(string): 2 string = string.replace("++","+") 3 string = string.replace("+-","-") 4 string = string.replace("-+","-") 5 string = string.replace("--","+") 6 return string 7 8 def addtion_reduce(s): #处理加减法,变成数组,全加 9 s = symbol_result(s) 10 li = re.findall(r'([d.]+|+|-)', s) 11 print (li) 12 sum = 0 13 14 for i in range(len(li)): 15 # 碰到 - 符号,就把 - 变成 + ,后面那个数字取反 16 if li[i] == '-': 17 li[i] = '+' 18 li[i+1] = float(li[i+1]) * (-1) 19 for i in li: 20 if i == '+': 21 i = 0 22 sum = sum + float(i) 23 return str(sum) 24 25 s = input("请输入公式:") 26 addtion_reduce(s)
完整代码
处理过程:
1.当字符串传入后,先处理空格。用字符串方法 replace 处理。
2.处理括号。循环条件,是否有 “(” 。如果有,表示还有括号。用 r'([^()]+)' 找到最里层括号,然后做计算。最终返回一个字符串。用这个字符串替换整个括号。
3.计算部分分两块,乘除和加减。先做乘除,乘除用 r'[d.]+[*/]-?[d.]+' 找到一个字符串。要用 search 一个个处理,findall 太麻烦。找到字符串之后,以 * / 为 分界线,计算。
4.加减 先处理 ++ +- -- 等问题,替换掉。然后把整个式子连同加减符号传入数组。把 - 变成 + ,后面那个元素取反。然后计算。
1 import re 2 3 def chengchu(s): #处理带负号的乘除 4 rRegex = re.compile(r""" 5 [d.]+ # 表示 3 或者 2.2 这样的数字. 6 [*/] # 乘除必有 7 -? # 最关键的,有可能出现 (6*-3) 这种式子 8 [d.]+ # 表示 3 或者 2.2 这样的数字. 9 # 连在一起就是 r'-?[d.]+[*/]-?[d.]+' 10 """,re.VERBOSE) 11 12 while (("*" in s) or ("/" in s)): 13 # 如果 "*" 或者 "/" 在字符串 s 中,表示还需要做乘除运算 14 15 ma = rRegex.search(s).group() # search 用 group 只找第一个 16 li = re.split(r'[*/]', ma) # ma 是一个式子,比如 -5.5*-5 。但是 while 里面 表示式子必定有 * 或者 /。以 * 或 / 为分隔符。 17 #float 左右两个 -5.5 和 -5。然后做乘除就可以了。 18 print(li,"li") 19 20 if ("*") in ma: 21 print(ma,"ma*") 22 result = str(float(li[0]) * float(li[1])) 23 else: 24 print(ma,"ma/") 25 result = str(float(li[0]) / float(li[1])) 26 s = s.replace(ma, result, 1) 27 28 return s 29 30 def symbol_result(string): 31 string = string.replace("++","+") 32 string = string.replace("+-","-") 33 string = string.replace("-+","-") 34 string = string.replace("--","+") 35 return string 36 37 def jiajian(s): #处理加减法,变成数组,全加 38 s = symbol_result(s) 39 li = re.findall(r'([d.]+|+|-)', s) 40 print (li) 41 sum = 0 42 43 for i in range(len(li)): 44 # 碰到 - 符号,就把 - 变成 + ,后面那个数字取反 45 if li[i] == '-': 46 li[i] = '+' 47 li[i+1] = float(li[i+1]) * (-1) 48 for i in li: 49 if i == '+': 50 i = 0 51 sum = sum + float(i) 52 return str(sum) 53 54 def simple(s): #处理不带括号的 55 return jiajian(chengchu(s)) 56 57 def complex(s): #处理带括号的 58 while '(' in s: 59 #如果检测到还有括号 60 61 # reg = re.compile(r'([^()]+)') # 表示最里层的括号)) 62 ma = re.search(r'([^()]+)', s).group() # 找到最里层括号内的字符串 63 result = simple(ma[1:-1]) # 用切片去除括号,计算字符串 64 s = s.replace(ma, result, 1) # 把原先最里层括号字符串替换成计算结果 65 return simple(s) 66 67 ss = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'.replace(' ', '') 68 # ss = "2*3*38*(2-3)".replace(" ","") 69 print(complex(ss)) 70 print(eval(ss))