痘疤脸

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

  尝试实现计算器功能,设计制作了2天,打了大概170行代码,最后功能是能够实现,但是依旧存在重大bug——不能对负数进行计算。

虽然可以添加大量if语句就可实现对于负数的判断来进行计算,但是显得代码不高效,所以先将代码放上来,以后在进行修改。

import re

# 四则运算
def yunsuan(jisuan):
    '''
    对传入的值进行四则运算
    :param jisuan:传输一个只包含一个符号两个数值的值
    :return: 返回一个经过四则运算的值
    '''
    # 抽取数值
    number = re.findall("\d+", jisuan)
    # 抽取符号
    fuhao = re.findall('[^\d]', jisuan)
    if fuhao[0] == "/":
        jieguo = int(number[0]) / int(number[1])
        jieguo = str(jieguo)
    if fuhao[0] == "*":
        jieguo = int(number[0]) * int(number[1])
        jieguo = str(jieguo)
    if fuhao[0] == "+":
        jieguo = int(number[0]) + int(number[1])
        jieguo = str(jieguo)
    if fuhao[0] == "-":
        jieguo = int(number[0]) - int(number[1])
        jieguo = str(jieguo)
    return jieguo

# 公式运算
def chouqu(txt):
    '''
    该模块主要是计算无括号时的算式,主要调用四则运算模块,然后将其运算结果替换其算式
    :param txt: 没有括号的算式
    :return: 返回输入这条算式的结果
    '''
    switch1 = True
    # 循环传入
    while switch1:
        # 检测是否含有运算符,无则退出
        fuhao_count = re.search("[\*|/]+|[+|-]+", txt)
        if fuhao_count == None:
            switch1 = False
            break
        # 提取只含一个运算符号的公式
        jisuan = re.search("[\d]+[\*|/][\d]+", txt)
        if jisuan == None:
            jisuan = re.search("[\d]+[+|-][\d]+", txt)
            jisuan = str(jisuan.group())
            zhi = yunsuan(jisuan)
        else:
            jisuan = str(jisuan.group())
            zhi = yunsuan(jisuan)
        zhi = str(zhi)
        # 对符号进行无意义化处理
        fuhao = re.search("[\*|/]+|[+|-]+", jisuan)
        fuhao = str(fuhao.group())
        if fuhao == "/":
            jisuan = re.sub("\/", "\/", jisuan)
        if fuhao[0] == "*":
            jisuan = re.sub("\*", "\*", jisuan)
        if fuhao[0] == "+":
            jisuan = re.sub("\+", "\+", jisuan)
        if fuhao[0] == "-":
            jisuan = re.sub("\-", "\-", jisuan)
        # 将对应的运算结果替换该运算公式
        txt = re.sub(jisuan, zhi, txt)
    return txt

cuowu = 0
switch = False
txt = input("请输入你想要计算的算式")
# 清除空格
txt = re.sub(" ", "", txt)
zuokuohao_count = re.findall("\(", txt)
youkuohao_count = re.findall("\)", txt)
# 判断括号数量
if youkuohao_count.__len__() == zuokuohao_count.__len__():
    switch = True
else:
    print("该算式缺少部分括号,请补齐")
# 判断是否连用符号
txt_fuhao = re.findall("[^\d\(\w\)]+", txt)
for i in txt_fuhao:
    if len(i) > 1:
        cuowu = 1
        switch = False
if cuowu == 1:
    print("该算式符号重叠 请重新输入")


while switch:
    # 判断是否含有括号
    txt1 = re.search("\([^\(\)]+\)", txt)
    if txt1 == None:
        switch = False
        break

    txt1 = str(txt1.group())
    # 取出括号内字符串
    number = str(re.findall("[^\(\)]+", txt1)[0])
    # 调用公式运算模块,计算出结果
    number = chouqu(number)
    # 将提取的括号算式符号无意义化
    zhuanhuan = re.sub("\*", "\*", txt1)
    zhuanhuan = re.sub("\+", "\+", zhuanhuan)
    zhuanhuan = re.sub("\(", "\(", zhuanhuan)
    txt1 = re.sub("\)", "\)", zhuanhuan)
    # 将括号内计算出来的值赋值到最初总算式中,并继续进行循环
    txt = re.sub(txt1, number, txt)
end_jieguo = chouqu(txt)
print(end_jieguo)

  实现计算器的过程,我的想法主要是将传入的算式进行分解,首先创建一个只针对一个符号两边的数值的运算函数,称为“四则运算”函数,该函数的返回值为结果,然后代替该运算算式。

  之后再将该“四则运算”函数嵌套进一个针对一整条算式且不包含“()”的运算函数当中去,称为“提取”函数,主要功能是将一整条算式不断进行四则运算,最后导出这条算式的值。

  最后我就是用了一个while循环来解决最后一步,针对“()”的运算,将括号内的算式提取之后再放入“提取”函数当中去,得出该算式结果,然后替换掉该括号内的算式,然后使用一个针对括号判断的if语句来控制while循环,不断循环去除括号后就只剩下一条算式,代入“提取”函数即可。

  依旧存在无法对负数进行计算的bug。

  在观看了其他人的另类的实现方案后,发现可以使用递归来进行计算,先做个标记,以后补充。

posted on 2018-09-11 13:47  痘疤脸  阅读(326)  评论(0编辑  收藏  举报