需求:用户输入一串公式 1 - 2 * ( (60-30 +(-40/5) * (9-2.3*3-9/(2.3*(-4))*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )
计算出最终结果(加减乘除括号的优先级要区分),代码中任意地方不可以调用eval函数,可以适当加一些合法性判断
以下为源码
import re def formatting(calculate_str): """ 格式化处理,将计算器接收到的表达式格式化处理,仅可处理合法内容 :param calculate_str: 用户输入 :return: 格式化处理后的表达式 """ while re.search(‘ |\+\+|\+-|-\+|--|\*\*‘,calculate_str): calculate_str = calculate_str.replace(‘ ‘, ‘‘) # 替换掉空格 calculate_str = calculate_str.replace(‘++‘, ‘+‘) # ++ 换成+ calculate_str = calculate_str.replace(‘+-‘, ‘-‘) # +- 换成- calculate_str = calculate_str.replace(‘-+‘, ‘-‘) # -+ 换成- calculate_str = calculate_str.replace(‘--‘, ‘+‘) # -- 换成+ calculate_str = calculate_str.replace(‘**‘, ‘^‘) # ** 换成^ 幂运算 return calculate_str def str_check(calculate_str): """ 判断传入的参数是否可以计算 :param calculate_str: (string)用户输入的需要计算的表达式 :return: 校验通过返回(string)表达式,校验失败返回False """ # 开始做合法性校验 if re.search(‘[^0-9+\-*/^.() ]‘,calculate_str): print(‘输入了数字或运算符以外的字符‘) return False elif len(re.findall(‘[(]‘,calculate_str)) != len(re.findall(‘[)]‘,calculate_str)): print(‘括号不匹配‘) return False return calculate_str def calculate(calculate_str): """ 计算一个没有括号的表达式 :param calculate_str:(string)需要计算的表达式 :return: (string)计算的结果 """ # 先算乘除 while ‘*‘ in calculate_str or ‘/‘ in calculate_str: i = re.search(‘[0-9]+\.?[0-9]*([*/]-?[0-9]+\.?[0-9]*)+‘, calculate_str).group() # 找到一个独立的运算单元 3*5/9*/3.9 market_list = re.findall(‘[*/]‘,i) # 找到所有的乘除运算符 num_list = re.split(‘[*/]‘,i) num = float(num_list[0]) for index,ii in enumerate(market_list): if ii == ‘*‘:num *= float(num_list[index + 1]) else:num /= float(num_list[index + 1]) calculate_str = calculate_str.replace(i,str(num)) calculate_str = formatting(calculate_str) # 算完乘除算加减 market_list = re.findall(‘[+\-]‘,calculate_str) num_list = re.split(‘[+\-]‘,calculate_str) if num_list[0] == ‘‘: num = 0 num_list.remove(num_list[0]) for index,i in enumerate(market_list): if i == ‘+‘:num += float(num_list[index]) else:num -= float(num_list[index]) else: num = float(num_list[0]) num_list.remove(num_list[0]) for index,i in enumerate(market_list): if i == ‘+‘:num += float(num_list[index]) else:num -= float(num_list[index]) return str(num) def input_str(): """ 接受用户输入并调用str_check函数,输入不合法重新输入 :return:用户要结束程序返回False,否则返回合法表达式 """ while True: s = input(‘请输入需要计算的表达式[输入q退出]:‘) if s == ‘q‘ or s == ‘Q‘: print(‘结束程序‘) return False s = str_check(s) if s:return formatting(s) def entrance(calculate_str): """ 程序的入口 :param calculate_str: input_str函数的返回值 :return: 计算结果 """ if not calculate_str:# 结束程序 return None while ‘(‘ in calculate_str: no_parentheses_unit = re.search(‘\([^()]+\)‘,calculate_str).group() try: return_str = calculate(no_parentheses_unit.strip(‘()‘)) except ValueError: print(‘遇到错误,请检查此处:‘) return False calculate_str = calculate_str.replace(‘%s‘% no_parentheses_unit,return_str) calculate_str = formatting(calculate_str) else: return_str = calculate(calculate_str) print(‘运算结果为%s‘% return_str) print(‘运算结果为%s‘% eval(s_str)) return return_str if __name__ == ‘__main__‘: # 懒得输入了 # s_str = ‘1 - 2 * ( (60-+30 +(-405 * (9-2*5/3 + 7 /3*9-9/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )‘ s_str = ‘1 - 2 * ( (60-30 +(-40/5) * (9-2.3*3-9/(2.3*(-4))*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )‘ go_on = entrance(str_check(s_str)) # s_str无法计算出结果才会执行 while not go_on: entrance(input_str())
我这里去掉了幂运算,有兴趣的小伙伴可以自己加一下功能