简单版计算器
解题思路
一、计算器运算规则
优先级 匹配格式
1. 小括号(最底层的) 括号里没有括号
小括号里算式计算优先级:
2.幂运算 (正数)**(正数)、(正数)**(负数) ---支持小数
3.乘除 (正数或负数)(*/)(正数或负数) ---支持小数
4.加减 (正数或负数)(+-)(正数或负数) ---支持小数
二、运算流程
1.search匹配第一个最底层的括号
2.通过match对象的groups方法获取括号里算式
3.对括号内的算式进行幂运算匹配
4.调用幂运算函数对匹配到的对象进行处理
5.用sub将结果替换括号内算式的匹配到的对象
6.重复3、4、5,直到没有匹配对象
7.对替换的算式进行乘除运算匹配
8.调用乘除运算函数对匹配到的对象进行处理
9.用sub将结果替换括号内算式的匹配到的对象
10.重复7、8、9直到没有匹配对象
11.对替换的算式进行加减运算匹配
12.调用加减运算函数对匹配到的对象进行处理
13.用sub将结果替换括号内算式的匹配到的对象
14.重复11、12、13直到没有匹配对象
15、重复上述步骤,直到没有括号
16.得到没有括号的算式后,只要再按照幂、乘除、加减步骤走
17.得到结果
流程图
我还发现python在处理运算时,会自动帮我们处理正负号,所以在匹配时不用太多的去关心数字前的正负号
代码实现
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 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | #题目:求得字符串里'1-2*((60-30+9*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'计算式的结果 import re #匹配规则 brackets = re. compile ( '\(([^()]+)\)' ) powers = re. compile ( '(\d+\.?\d*)\*\*(\-?\d+\.?\d*)' ) mul_div = re. compile ( '(\-?\d+\.?\d*)([*/])(\-?\d+\.?\d*)' ) add_cut = re. compile ( '(\-?\d+\.?\d*)([+\-])(\-?\d+\.?\d*)' ) def powers_calculate(match_obj): ''' 处理幂运算 :param match_obj: 需要处理的match对象 :return:算式的结果 ''' mat_grs = match_obj.groups() n1 = float (mat_grs[ 0 ]) n2 = float (mat_grs[ 1 ]) return n1 * * n2 def mul_div_calculate(match_obj): ''' 处理乘除运算 :param match_obj: 需要处理的match对象 :return: 算式的结果 ''' mat_grs = match_obj.groups() n1 = float (mat_grs[ 0 ]) n2 = float (mat_grs[ 2 ]) if mat_grs[ 1 ] = = '*' : return n1 * n2 else : return n1 / n2 def add_cut_calculate(match_obj): ''' 处理加减运算 :param match_obj: 需要处理的match对象 :return: 算式的结果 ''' mat_grs = match_obj.groups() n1 = float (mat_grs[ 0 ]) n2 = float (mat_grs[ 2 ]) if mat_grs[ 1 ] = = '+' : return n1 + n2 else : return n1 - n2 #数据源 data_sour = '1-2*((60-30+9*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))' # data_sour = input('请输入你要计算的算式:') #================================================================================== #匹配最底层的括号 brackets_match = brackets.search(data_sour) #对匹配到的括号进行处理 while True : if brackets_match: #判断匹配成功与否 print (brackets_match.group()) #(9-2*5/3+7/3*99/4*2998+10*568/14) mat_groups1 = brackets_match.groups() #得到去括号的组的值,不过此时这里是元组 print (mat_groups1) #('9-2*5/3+7/3*99/4*2998+10*568/14',) #处理幂运算 text = mat_groups1[ 0 ] #得到最底层括号里的算式字符串 powers_match = powers.search(text) #匹配幂运算 while True : if powers_match: #判断匹配成功与否 print (powers_match.group()) ret1 = powers_calculate(powers_match) #调用幂运算函数 print (ret1) text = re.sub(powers, str (ret1),text, 1 ) #把得到的幂运算结果替换匹配到的字符串 powers_match = powers.search(text) #对替换的字符串再次进行幂运算匹配 else : break #匹配失败,就退出匹配幂运算的循环 #处理乘除运算 mul_div_match = mul_div.search(text) #对处理幂运算后的字符串进行乘除运算匹配 while True : if mul_div_match: #判断匹配成功与否 print (mul_div_match.group()) ret2 = mul_div_calculate(mul_div_match) #调用乘除运算函数 print (ret2) text = re.sub(mul_div, str (ret2),text, 1 ) #把得到的乘除运算结果替换匹配的字符串 print (text) mul_div_match = mul_div.search(text) #对处理后的字符串再进行乘除运算匹配 else : break #匹配失败,就退出匹配乘除运算的循环 #处理加减运算 add_cut_match = add_cut.search(text) #对处理乘除后的字符串进行加减运算匹配 while True : if add_cut_match: #判断匹配成功与否 print (add_cut_match.group()) ret3 = add_cut_calculate(add_cut_match) #调用加减运算函数 text = re.sub(add_cut, str (ret3),text, 1 ) #用得到的加减运算结果替换匹配的字符串 print (text) add_cut_match = add_cut.search(text) #对处理后的字符串再进行加减运算匹配 else : break #匹配失败,退出匹配加减运算的循环 data_sour = re.sub(brackets,text,data_sour, 1 ) #把括号里的计算结果替换匹配的括号 brackets_match = brackets.search(data_sour) #再次对处理后字符串进行括号的匹配 else : break #匹配不到括号,就退出匹配括号的循环 #对处理括号完后的算式进行最后的运算 #幂 powers_match = powers.search(data_sour) while True : if powers_match: ret1 = powers_calculate(powers_match) data_sour = re.sub(powers, str (ret1),data_sour, 1 ) powers_match = powers.search(data_sour) else : break #乘除 mul_div_match = mul_div.search(data_sour) while True : if mul_div_match: ret1 = mul_div_calculate(mul_div_match) data_sour = re.sub(mul_div, str (ret1), data_sour, 1 ) mul_div_match = mul_div.search(data_sour) else : break #加减 add_cut_match = add_cut.search(data_sour) while True : if add_cut_match: ret1 = add_cut_calculate(add_cut_match) data_sour = re.sub(add_cut, str (ret1), data_sour, 1 ) add_cut_match = add_cut.search(data_sour) else : break print ( '最后结果为:' ,data_sour) #验证结果 data_sour = '1-2*((60-30+9*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))' jieguo = eval (data_sour) print ( '验证结果:' ,jieguo) |
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步