
开发一个简单的python计算器
1.实现加减乘除及括号优先级解析
2.用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )
等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式(不能调用eval等类似功能实现), 运算后得出结果,结果必须与真实的计算器所得出的结果一致
分析:
一、判断用户输入的公式是否正确(下面只做了4条,其它暂无添加)
1、先去除空格
2、不能出现字母
3、"("与")"必须配对
4、+、-、*、/不能重复
二、考虑优先级,先算()内部,再算*/,最后算+-
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re
from functools import reduce # 检查表达式合法性
def check_formula(formula):
tag = True
if re.findall("[a-zA-Z]", formula): # 包含字母
tag = False
if not len(re.findall("\(", formula)) == len(re.findall("\)", formula)): # (与)不匹配
tag = False
if re.findall("\(\)", formula): # 只出现()
tag = False
return tag # 去掉重复的运算符
def repeat_operator(formula):
formula = formula.replace("++", "+")
formula = formula.replace("-+", "-")
formula = formula.replace("+-", "-")
formula = formula.replace("--", "+")
return formula # 计算乘除运算
def count_mul_div(formula):
is_have_muldiv = re.search("\d+\.?\d*[*/]\-?\d+\.?\d*", formula) # 匹配含有*/运算的表达式
if is_have_muldiv:
bracketin_formula = is_have_muldiv.group()
x, y = re.split("[*/]", bracketin_formula) # 以*或/分割得到两个数据
mul_or_div = re.search("[*/]", bracketin_formula).group() # 获取运算符
if mul_or_div == "*":
operation_result = float(x) * float(y)
else:
operation_result = float(x) / float(y)
operation_result = str(operation_result)
formula = formula.replace(bracketin_formula, operation_result) # 将乘除结果替换上面找到的乘除运算
return count_mul_div(formula) # 有*/,继续调用自己做乘除
else:
return count_add_sub(formula) # 没有*/,调用加减计算 # 计算加减运算
def count_add_sub(formula):
formula = repeat_operator(formula)
is_have_muldiv = re.search("\-?\d+\.?\d*[+\-]\d+\.?\d*", formula) # 匹配含有+-运算的表达式
if is_have_muldiv:
bracketin_formula = is_have_muldiv.group()
nums_list = re.findall("\-?\d+\.?\d*", bracketin_formula) # 匹配除+号外的数字
operation_result = reduce(lambda x, y: float(x) + float(y), nums_list) # reduce求和
operation_result = str(operation_result)
formula = formula.replace(bracketin_formula, operation_result) # 将加减结果替换上面找到的加减运算
return count_add_sub(formula) # 继续调用自己做加减运算
else:
formula = formula.strip("()") # 将运算结果外面()去掉
return formula # 没有+-,运算完成,返回运算结果 # 主逻辑
while True:
formula = re.sub(" +", "", input("请输入数学表达式或按q退出:")) # 输入表达式,去除空格
result = None
if formula.lower() == "q":
break
else:
if check_formula(formula): # 判断表达式合法性
is_bracket_flag = True
while is_bracket_flag:
formula = repeat_operator(formula) # 去除重复运算符
bracket_bestin = re.search("\([^()]*\)", formula) # 找最内层括号
if bracket_bestin:
bracket_bestin = bracket_bestin.group()
result = count_mul_div(bracket_bestin) # 调用乘除计算
formula = formula.replace(bracket_bestin, result) # 替换原表达式的内层括号
else:
is_bracket_flag = False # 找不到括号
result = count_mul_div(formula) # 调用乘除计算
else:
print("输入表达式有误!")
if result:
print(result)
代码