模拟计算器开发作业
要求:
1、实现加减乘除及拓号优先级解析
2、用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式(不能调用eval等类似功能偷懒实现),运算后得出结果,结果必须与真实的计算器所得出的结果一致
思路:
1、定义正负的乘除法运算
2、定义计算的优先级
3、将复杂运算括号中的算式优先计算,运算结果合并入算式中,最后将算式变成简单的加减乘除运算再计算结果
流程图:

code:
#!/usr/bin/env python #-*- coding:utf-8 -*- # Author:summer_han import re import sys def mult_div(l,x): ''' 定义最小 乘法和除法单元 并计算后 只剩下 加减法 ,l 为 正则转换后的 list, x 代表 * 或者 / :param l: :param x: :return: ''' p = l.index(x) # print(p,l) # 定义 x 为 * 时 x 的下一位 是否为 -,如果 为 - 则 为负数 if x == '*' and l[p+1] != "-": r = float(l[p-1]) * float(l[p+1]) elif x == '*' and l[p+1] == "-": r = -(float(l[p-1]) * float(l[p+2])) # 定义 x 为 / 时 x 的下一位 是否为 -,如果 为 - 则 为负数 elif x == '/' and l[p+1] != "-": r = float(l[p-1]) / float(l[p+1]) elif x == '/' and l[p+1] == "-": r = -(float(l[p-1]) / float(l[p+2])) # 三个位置 计算后 ,删除 3个位置的元素 del l[p-1],l[p-1],l[p-1] # 将 计算结果插入到删除位置 l.insert(p-1,str(r)) def func(exps): ''' 函数计算主体,负责计算 只有加减乘除的运算 :param exps:算式参数 :return:返回计算结果 ''' rel=re.findall('([\d\.]+|/|-|\+|\*)',exps) # print("打印初始列表",rel) # 当rel为真时 while True: # 既有乘法又有除法运算符时,判断乘除法运算符位置,位置小的优先计算 if '*' in rel and '/' in rel: pos_A = rel.index('*') pos_B = rel.index('/') # 判断 乘除法运算符 位置 if pos_A < pos_B: mult_div(rel,'*') # print(rel) # 打印rel 对比 list else: mult_div(rel,'/') # 只有 乘法 没有 除法 elif '*' in rel and '/' not in rel: mult_div(rel,'*') # 只有 除法 没有 乘法 elif '*' not in rel and '/' in rel: mult_div(rel,'/') else: # 初始化 运算结果为 0 sum = 0 # 判断列表第一个元素是否为 '-' 如果为 '-' 则合并 前两个元素,并且删除第二个元素 rel[1],保留合并后的元素 if rel[0] == '-': rel[0] = rel[0] + rel[1] # 删除合并后的无用 元素 del rel[1] # 打印结果查看列表元素是否正确 # print(rel) # 初始化运算结果 为列表第一个元素的值 sum += float(rel[0]) # print('---------------',sum) # 判断元素符号,范围为1到列表最大长度,步长为2 for i in range(1,len(rel),2): # 打印 符号 (+ -) # print(rel[i]) # 判断 + 后后面是否是'-',如果不是'-' 则 sum结果为 加下一位 if rel[i] == '+' and rel[i+1] != '-': sum += float(rel[i+1]) # 判断 + 后面是否为 '-',如果是'-',则 sum 结果为 - i+2位 (i+1位是'-') elif rel[i] == '+' and rel[i+1] == '-': sum -= float(rel[i+2]) # 判断 - 后后面是否是'-',如果不是'-' 则 sum结果为 减下一位 elif rel[i] == '-' and rel[i+1] != '-': sum -= float(rel[i+1]) # 判断 - 后后面是否是'-',如果是'-' 则 sum结果为 加下一位 elif rel[i] == '-' and rel[i+1] == '-': sum += float(rel[i+2]) # print(sum) return sum # expression = '-100.5+40*5/2-3*2*2/4+9' def calculate(exps): ''' 负责算式的分解,循环将()内的算式计算,最后将结果变成加减乘除运算在计算出结果 :param exps:用户输入的算式 :return:算式结果 ''' #定义提取 括号类元素的临时列表 tmpex = [] rlt = 0 if '(' not in exps: rlt = func(exps) # print(rlt) return rlt else: # len(exps) 长度 从 0 开始 for i in range(len(exps)): if exps[i] == '(': tmpex.append(i) # print("\033[41;1m ( 的位置:\033[0m",tmpex) elif exps[i] == ')': # print("\033[35;1m括号取值位置判断:\033[0m",(tmpex[len(tmpex)-1])+1,i) # len(tmpex) 长度, len(tmpex)-1 为列表tmpex最后一个元素,因为从0开始计算第一个元素; # (tmpex[len(tmpex)-1])+1 为最后一个元素'('下一位的位置,在 exps 中取值,i为第一个出现的')' subexpr = exps[tmpex[len(tmpex)-1]+1:i] # 19-26 # print("\033[42;1m子运算式\033[0m",subexpr) temp=func(subexpr) # print("\033[43;1m 存放临时结果 \033[0m",temp) # 初始化 exps 列表 # len(tmpex-1) 为tmpex长度的最后一个元素 在exps 中 0到最后一个元素 )的位置,不取 ) # 和 第一个最内层()的字运算结果 str(temp)合并,在和exps的[i+1]位到最后一个元素合并 # 作为新的 exps ,以此类推循环 ,每次循环计算 str(temp)的值 exps = exps[0:tmpex[len(tmpex)-1]]+str(temp)+exps[i+1:] # 删除tmpex中最后一个元素 tmpex.pop() return calculate(exps) if __name__ == '__main__': while True: exps = input("\033[31;1m请输入您的要计算的算式:\033[0m") print("\033[35;1mcalculate程序运行计算结果为:%s \neval执行结果为:%s\033[0m"%(calculate(exps),eval(exps))) flag = input("按【q】退出程序,或者按任意键继续:") if flag == 'q': sys.exit("\033[42;1mExit the calculate program,Bye!\033[0m".center(50,'-')) else: continue # exps = '2+10-((6-3)*2+(5-2)*3)' # exps = '-100.5+40*5/2-3*2*2/4+9' # exps = '1 - 2 * ( (60-30 +(-40/5+3) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'

浙公网安备 33010602011771号