module022计算器

需求

  • 实现加减乘除及扩号优先级解析
  • 用户输入 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 #! /usr/bin/env python3
  2 # -*- coding:utf-8 -*-
  3 # Author:Jailly
  4 
  5 import re
  6 
  7 # 匹配单次加减运算表达式的re编译对象
  8 sub_pm = re.compile(r'''
  9 \s*
 10 (?P<operand1>((-?[1-9]\d*)|0)(\.\d+)?)  # 第一个操作数
 11 \s*
 12 (?P<operator>[+-])  # 操作符
 13 \s*
 14 (?P<operand2>((-?[1-9]\d*)|0)(\.\d+)?)  # 第二个操作数
 15 ''', re.X)
 16 
 17 # 匹配单次乘除运算表达式的re编译对象
 18 sub_md = re.compile('''
 19     \s*
 20     (?P<operand1>((-?[1-9]\d*)|0)(\.\d+)?)  # 第一个操作数
 21     \s*
 22     (?P<operator>[*/])  # 操作符
 23     \s*
 24     (?P<operand2>((-?[1-9]\d*)|0)(\.\d+)?)  # 第二个操作数
 25 ''',re.X)
 26 
 27 
 28 def pm(exp):
 29     '''
 30     最底层的加减,无乘除,无括号
 31     :param exp:只含有加减的运算式字符串
 32     :param sub_pm:匹配单次加减运算表达式的re编译对象
 33     :return:递归返回将逐次运算结果代入原式后的表达式
 34     '''
 35 
 36     sub_exp = sub_pm.search(exp)
 37 
 38     if sub_exp:
 39         operand1 = float(sub_exp.group('operand1'))
 40         operand2 = float(sub_exp.group('operand2'))
 41         res = ( operand1 + operand2 ) if sub_exp.group('operator') == '+' else ( operand1 - operand2 )
 42 
 43         # 从左到右计算,只取匹配到的第一个替换,count = 1
 44         new_exp = sub_pm.sub(str(res),exp,count=1)
 45 
 46         return pm(new_exp)
 47 
 48     else:
 49         return exp
 50 
 51 
 52 def md(exp):
 53     '''
 54     最底层的乘除,可有加减,但无括号
 55     :param exp:只含有乘除的运算式字符串
 56     :return:递归返回将逐次运算结果代入原式后的表达式
 57     '''
 58     sub_exp = sub_md.search(exp)
 59 
 60     if sub_exp:
 61         operand1 = float(sub_exp.group('operand1'))
 62         operand2 = float(sub_exp.group('operand2'))
 63         res = ( operand1 * operand2 ) if sub_exp.group('operator') == '*' else ( operand1 / operand2 )
 64 
 65         # 从左到右计算,只取匹配到的第一个替换,count = 1
 66         new_exp = sub_md.sub(str(res),exp,count=1)
 67 
 68         return md(new_exp)
 69     else:
 70         return exp
 71 
 72 
 73 def brackets(exp):
 74     '''
 75     供brackets2调用,计算括号内的运算式
 76     :param exp:只含有单层括号的运算式字符串
 77     :return:运算结果的字符串形式
 78     '''
 79 
 80     exp1 = md(exp)
 81     exp2 = pm(exp1)
 82 
 83     res = re.search(r'\((?P<res>.+)\)',exp2).group('res')
 84     
 85     return res
 86 
 87 def brackets2(exp):
 88     '''
 89     多层括号运算
 90     :param exp:含有多层括号的运算式字符串
 91     :return:
 92     '''
 93     min_bra_c = re.compile(r'\([^()]+\)')
 94     min_bra_m = min_bra_c.search(exp)
 95 
 96     if min_bra_m:
 97         min_bra_exp = min_bra_m.group()
 98         res = brackets(min_bra_exp)
 99         new_exp = min_bra_c.sub(res,exp,count=1)
100 
101         return brackets2(new_exp)
102     else:
103         return exp
104 
106 
107 def calc(exp):
108     '''主程序'''
109 
110     exp1 = brackets2(exp)
111     exp2 = md(exp1)
112     exp3 = pm(exp2)
113 
114     return float(exp3)
115 
116 
117 if __name__ == '__main__':
118 
119     while 1:
120         q = input('请输入您的运算式:')
121         if q == 'q':
122             exit()
123         else:
124             try:
125                 print('结果为:\033[1;31m %s \033[0m'%str(calc(q)))
126             except:
127                 print('\033[1;31m请输入正确的运算式!\033[0m')
原文地址:https://www.cnblogs.com/jailly/p/6917232.html