python基础篇14-计算器练习
要求:
# 实现加减乘除及拓号优先级解析 # 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) ) # 等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式(不能调用eval等类似功能偷懒实现),运算后得出结果, # 结果必须与真实的计算器所得出的结果一致
1 #__author: lriwu 2 #date 2018/1/30 3 4 # 实现加减乘除及拓号优先级解析 5 # 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) ) 6 # 等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式(不能调用eval等类似功能偷懒实现),运算后得出结果, 7 # 结果必须与真实的计算器所得出的结果一致 8 9 import re 10 11 def check_expression(string): 12 ckeck_result = True 13 #检查括号是否匹配 14 if not string.count('(') == string.count(')'): 15 print("表达式错误,括号未闭合") 16 ckeck_result = False 17 if re.findall('[a-z]+',string.lower()): 18 print("表达式错误,含非法字符") 19 ckeck_result = False 20 21 return ckeck_result 22 23 24 def format_string(string): 25 string = string.replace(' ','') 26 string = string.replace('+-','-') 27 string = string.replace('-+', '-') 28 string = string.replace('++', '+') 29 string = string.replace('--', '+') 30 string = string.replace('*+', '*') 31 string = string.replace('/+', '/') 32 return string 33 34 def calc_mul_div(string): 35 # 从字符串中获取乘除表达式 (-3.1*-2.1+1-2*3) 36 regular = '\d+\.?\d*([*/]|\*\*)[\-]?\d+\.?\d*' 37 #如果还能找到乘或除表达式 38 while re.findall(regular,string): 39 #获取表达式 40 expression = re.search(regular,string).group() 41 42 #如果时乘法 43 if expression.count('*') == 1: 44 #获取要计算的两个数 45 x,y = expression.split('*') 46 #计算结果 47 mul_result = str(float(x) * float(y)) 48 #将计算的表达式替换为计算的结果值 49 string = string.replace(expression,mul_result) 50 string = format_string(string) 51 52 # 如果时除法 53 if '/' in expression: 54 # 获取要计算的两个数 55 x, y = expression.split('/') 56 # 计算结果 57 mul_result = str(float(x) / float(y)) 58 # 将计算的表达式替换为计算的结果值 59 string = string.replace(expression, mul_result) 60 string = format_string(string) 61 62 return string 63 64 65 def calc_add_sub(string): #(-2.1+2.1-1+2) 66 #定义正则表达式 67 add_regular = '\-?\d+\.?\d*\+\-?\d+\.?\d*' 68 sub_regular = '\-?\d+\.?\d*\-\-?\d+\.?\d*' 69 # 从字符串中获取加减表达式 70 # 计算加法 71 while re.findall(add_regular, string): 72 # 获取表达式 73 add_list = re.findall(add_regular, string) 74 for add_str in add_list: 75 #获取两个加法的数 76 x,y = add_str.split('+') 77 add_result = '+'+str(float(x) + float(y)) 78 string = string.replace(add_str,add_result) 79 string = format_string(string) 80 81 #计算减法 82 while re.findall(sub_regular, string): 83 # 获取表达式 84 sub_list = re.findall(sub_regular, string) 85 for sub_str in sub_list: 86 #获取两个减法的数 87 members = sub_str.split('-') 88 if len(members) == 3: 89 sub_result = 0 90 for v in members: 91 sub_result -= float(sub_result) #sub_result = sub_result -float(sub_result) 92 93 else: 94 x,y = members 95 sub_result = float(x) - float(y) 96 97 string = string.replace(sub_str, "+"+str(sub_result)) 98 string = format_string(string) 99 return string 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 if __name__ == '__main__': 117 source = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )' 118 if check_expression(source): 119 print("source:",source) 120 print("eval result:",eval(source)) 121 source = format_string(source) 122 print(source) 123 124 while source.count('(') > 0: 125 strs = re.search('\([^()]+\)',source).group() #['(-40/5)', '(9-2*5/3+7/3*99/4*2998+10*568/14)', '(-4*3)', '(16-3*2)'] 126 #将括号的表达式进行乘除运算 127 replace_str = calc_mul_div(strs) 128 129 #将括号的表达式进行加减运算 130 replace_str = calc_add_sub(replace_str) 131 132 #将括号的字符串替换为计算结果,结果包含括号(),替换时去掉括号():[1:-1] 133 source = format_string(source.replace(strs,replace_str[1:-1])) 134 #没有括号就到最后单一表达式了 135 else: 136 #算乘除 137 replace_str = calc_mul_div(source) 138 #算加减 139 replace_str = calc_add_sub(replace_str) 140 source = source.replace(source,replace_str) 141 #source = source.replace(source, replace_str)) 142 143 print(source)