功能: 通过输入一个长字符串得到结果
包括函数:
format_string(string):
将传入的字符串string中的类似于"--","-+","+-","==","*+","/+" 格式化
calc_mul_div(string):
对传入的字符串进行乘法、除法计算,返回仅有加、减的表达式
calc_add_sub(string)
对传入的字符串进行加、减运算,返回计算结果
设计思路:
1 将表达式先进行去括号,返回不包含括号的单一表达式
2 将得到的单一表达式先进行乘、除运算,并用字符串替换的方式将计算表达式替换为计算结果。直到表达式只剩下加、减运算符号。
3 将第二步计算的结果再进行加、减运算,并进行字符串替换,直到计算出表达式结果
4 将第三步计算的结果替换第一步的表达式。
包括函数:
format_string(string):
将传入的字符串string中的类似于"--","-+","+-","==","*+","/+" 格式化
calc_mul_div(string):
对传入的字符串进行乘法、除法计算,返回仅有加、减的表达式
calc_add_sub(string)
对传入的字符串进行加、减运算,返回计算结果
设计思路:
1 将表达式先进行去括号,返回不包含括号的单一表达式
2 将得到的单一表达式先进行乘、除运算,并用字符串替换的方式将计算表达式替换为计算结果。直到表达式只剩下加、减运算符号。
3 将第二步计算的结果再进行加、减运算,并进行字符串替换,直到计算出表达式结果
4 将第三步计算的结果替换第一步的表达式。
5 只要表达式中包含"(",重复以上步骤直到表达式不包含任何括号
流程图:
源码:
#!/usr/bin/env python # -*- coding: utf-8 -*- import re # 格式化字符串 def format_string(string): string = string.replace("--", "+") string = string.replace("-+", "-") string = string.replace("++", "+") string = string.replace("+-", "-") string = string.replace("*+", "*") string = string.replace("/+", "/") string = string.replace(' ', '') return string # 检查表达式合法性 def check_expression(string): check_result = True # 括号是否匹配 if not string.count("(") == string.count(")"): print("表达式错误,括号未闭合!") check_result = False if re.findall('[a-z]+', string.lower()): print("表达式错误,包含非法字符!") check_result = False return check_result # 计算乘 、除法 def calc_mul_div(string): # 从字符串中获取一个乘法或除法的表达式 regular = "\d+\.{0,}\d{0,}[\*\/][\-]{0,}\d+\.{0,}\d{0,}" # 如果还能找到乘或除法表达式 while re.findall(regular, string): # 获取表达式 expression = re.search(regular, string).group() # 如果是乘法 if expression.count("*"): # 获取要计算的两个数 x, y = expression.split("*") # 计算结果 mul_result = str(float(x) * float(y)) # 将计算的表达式替换为计算结果值 string = string.replace(expression, mul_result) # 格式化一下 string = format_string(string) # 如果是除法 if expression.count("/"): # 获取要计算的两个数 x, y = expression.split("/") # 计算除法 div_result = str(float(x) / float(y)) # 用结果替换表达式 string = string.replace(expression, div_result) string = format_string(string) return string # 计算加、减法 def calc_add_sub(string): # 定义正则表达式 add_regular = "[\-]{0,}\d+\.{0,}\d{0,}\+[\-]{0,}\d+\.{0,}\d{0,}" sub_regular = "[\-]{0,}\d+\.{0,}\d{0,}\-[\-]{0,}\d+\.{0,}\d{0,}" # 开始加法 while re.findall(add_regular, string): # 把所有的加法都算完,获取所有加法表达式 add_list = re.findall(add_regular, string) for add_str in add_list: # 获取两个加法的数 x, y = add_str.split("+") add_result = "+" + str(float(x) + float(y)) string = string.replace(add_str, add_result) string = format_string(string) # 开始减法 while re.findall(sub_regular, string): sub_list = re.findall(sub_regular, string) for sub_str in sub_list: numbers = sub_str.split("-") # -3-5的情况split会返回3个值 if len(numbers) == 3: result = 0 for v in numbers: if v: result -= float(v) else: x, y = numbers result = float(x) - float(y) # 替换字符串 string = string.replace(sub_str, "+" + str(result)) string = format_string(string) return string if __name__ == "__main__": source = "1 - 2 * ( (60-30 +(-9-2-5-2*3-5/3-40*4/2-3/5+6*3) * (-9-2-5-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )" if check_expression(source): print("source: ", source) print("eval result: ", eval(source)) while source.count("(") > 0: # 格式化 source = format_string(source) # 去括号,得到括号的字符串,结果如:(30+6/3) strs = re.search('\(([/-]*\d+\.*\d*[\+\-\*/]+)+\d+\.*\d*\)', source).group() # 将括号的表达式进行乘、除运算 replace_str = calc_mul_div(strs) # 将运算的结果在进行加、减运算 replace_str = calc_add_sub(replace_str) # 将括号的字符串替换为计算结果,结果包含(),替换时去掉():[1:-1] source = format_string(source.replace(strs, replace_str[1:-1])) else: # 没有括号就到最后单一表达式了 replace_str = calc_mul_div(source) # 算乘除 replace_str = calc_add_sub(replace_str) # 算加减 source = source.replace(source, replace_str) print("my result: ", source.replace("+", ""))