代码写的有些乱,还没有仔细优化一下,主要通过此例子掌握正则表达式的使用
主要用到了 re.split()和 re.match
走了很多弯路,集中在正则表达式上面,还是因为不熟练
剩下的问题就是算法了,列表中前后元素相关联的问题
# Author:Winter Liu is coming! import re # 使用左右括号分隔字符串,并去除空元素 def baraket_handle(s): pattern = r"(()|())" # 注意,切割时,如果前后没有对象,会构成一个空字符串 ret = re.split(pattern, s) ret = filter(lambda x: x, ret) return list(ret) # 判断是否为数值 def isfloat(s): p = r"(d+.?d*)$" return re.match(p, s) # 切割字符串,将列表中的数值字符串转换为浮点数,为下一步的计算做准备 # 特别注意负数的问题处理 def convert(s): print("s=",s) p = r"([*/+-])" r = re.split(p, s) print("r=", r) num = [] # 用于存放分割的列表中处理过的结果,只包含浮点数和运算符 i = 0 while i < len(r): if r[i] == "": # 切割时,如果前后没有对象,会构成一个空字符串 num.append(-float(r[i+2])) # 空字符串表明此处为负数,正常情况前后都有数字 i += 3 # 跳过三个到下一次判断 continue if isfloat(r[i]): num.append(float(r[i])) # 普通数字 else: num.append(r[i]) # 运算符 i += 1 print("num=",num," ") return num # 使用convert函数的转换结果,进行计算,注意计算顺序 def comput(num): while ("*" in num) or ("/" in num): # 先计算全部乘法和除法 n = len(num) for i in range(1, n, 2): # 通过前面的处理,运算符只出现在偶数位置上 if num[i] in "/*": if num[i] == "/": # 将计算结果替换原有表达式,保存在原列表位置 num[i] = num[i-1] / num[i+1] else: num[i] = num[i-1] * num[i+1] del num[i - 1] del num[i] break # print("**", num) while ("+" in num) or ("-" in num): n = len(num) for i in range(1, n, 2): if num[i] in "-+": if num[i] == "+": num[i] = num[i-1] + num[i+1] else: num[i] = num[i-1] - num[i+1] del num[i - 1] del num[i] break # print("****", num) return num[0] exp = r"1-2*(30+40*(55/66+(34*90-34)/7)-70*(8-9*1-3/4))+(-4*2)/((16-3)*2/3+7)" print(eval(exp)) res = baraket_handle(exp) print(exp) while len(res) > 1: # 循环到列表中只剩下一个元素,就是最终结果 new_res = [] n = len(res) i = 0 while i < n: if res[i] == "(" and res[i + 2] == ")": num = convert(res[i + 1]) # 对括号中间部分的字符串进行处理技术 # print(num) x = comput(num) new_res.append(str(x)) # 将计算结果保存在原有位置 i += 3 else: new_res.append(res[i]) i += 1 # print(new_res) exp = "".join(new_res) # 生成新的字符串 print(exp) if "(" in exp: # 如果字符中没有括号了,可直接处理计算,否则处理括号 res = baraket_handle(exp) else: res = comput(convert(exp)) break print(res)