python实现基本计算器(可处理括号和负值)

代码写的有些乱,还没有仔细优化一下,主要通过此例子掌握正则表达式的使用

主要用到了 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)
原文地址:https://www.cnblogs.com/nmucomputer/p/12779700.html