zoukankan      html  css  js  c++  java
  • 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)
  • 相关阅读:
    selenium 在爬虫中的应用
    基于scrapy-redis的第二种形式的分布式爬虫(把普通scrapy框架转成分布式)
    django html 模板继承(下)加精
    django页面之间的前端模板继承或者引入详解(上)
    inclusion_tag 重复页面加载显示模板
    django ForeignKey ManyToManyField OneToOneField
    django建站的注意点
    任务19
    数列求和
    鸡兔同笼2
  • 原文地址:https://www.cnblogs.com/nmucomputer/p/12779700.html
Copyright © 2011-2022 走看看