Python小算法 -- 原始计算器功能

使用基本语法计算类似如下算式的结果:

5- 3 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 ))- (-4*3)/(16-3*2))

计算思路:

1、基本判断,输入的算式括号是否成对

2、依次获取最内层括号内的算式,按先乘除后加减计算结果,再将结果替换算式,直到算式中无括号为止

3、将没有括号的算式,按先乘除后加减计算结果

注:计算过程中要考虑减号重复,将--替换为+,将+-替换为-,同时要考虑小数的情况。

详细代码:

import re
#检查括号是否合法成对出现,利用堆栈思想
def checkBracket(expression):
    bracketList=[]
    for i in expression:
        if i == '(':
            bracketList.append(i)
        elif i == ')':
            if len(bracketList)==0:
                return False
            else:
                bracketList.pop()
    if len(bracketList)==0:
        return True
    else:
        return False

#计算乘除法算式
def multiplyDivide(expression):
    if '*' in expression:
        left,right=expression.split('*')
        return str(float(left)*float(right))
    elif '/' in expression:
        left,right=expression.split('/')
        return str(float(left)/float(right))

#去除算式中的减号重复
def removeDouble(expression):
    expression=expression.replace('--','+')
    expression=expression.replace('+-','-')
    return expression

#计算算式结果,先乘除后加减
def calcResult(expression):
    while True:
        mulDiv=re.search('\d+(\.\d+)?[*/]-?\d+(\.\d+)?',expression) #循环查找乘法或除法算式,依次计算结果
        if mulDiv:
            mulDiv=mulDiv.group()
            mulResult=multiplyDivide(mulDiv) #调用乘除法计算结果
            expression=expression.replace(mulDiv,mulResult) #用结果替换乘法或除法算式
            expression=removeDouble(expression) #去除重复减号
        else:
            #乘除法计算完成后,剩下加减法,把算式中所有数字(包含负数)提取出来,相当于用+号split,再循环计算求和
            numPlus=re.findall('-?\d+(?:\.\d+)?',expression)
            sum=0
            for i in numPlus:
                sum+=float(i)
            return str(sum)

#主体计算函数,提取最内层括号算式,依次计算
def calcExpression(expression):
    while True:
        expressBracket=re.search('\([^()]+\)',expression) #依次查找最内层括号算式
        if expressBracket:
            expressBracket=expressBracket.group()
            ret=calcResult(expressBracket) #调用函数计算内层括号内的算式
            expression=expression.replace(expressBracket,ret)
        else:
            ret=calcResult(expression) #直到算式无括号,再计算算式
            return ret

if __name__ == '__main__':
    inputExpression=input('输入计算式:')
    if checkBracket(inputExpression):
        inputExpression=inputExpression.replace(' ','').strip() #去除算式的空格及空白符
        ret=calcExpression(inputExpression) #调用主计算函数
        print('计算结果为:'+ret)
        print('Python eval计算结果为:'+str(eval(inputExpression))) #调用python自带的eval函数验算结果
    else:
        print('输入计算式不合法!')

方法2:整体思路一样,无判断括号合法,乘除功能函数分开

代码如下

import re
def atomCalc(exp):
    if '*' in exp:
        a,b=exp.split('*')
        return str(float(a)*float(b))
    elif '/' in exp:
        a,b=exp.split('/')
        return str(float(a)/float(b))

def mulDiv(exp):
    while 1:
        mulDivExp = re.search('\d+(\.\d+)?[*/]-?\d+(\.\d+)?', exp)
        if mulDivExp:
            atomExp=mulDivExp.group()
            res=atomCalc(atomExp)
            exp=exp.replace(atomExp,res)
        else:
            return exp

def addSub(exp):
    addSubExp=re.findall('-?\d+(?:\.\d+)?',exp)
    expSum=0
    for i in addSubExp:
        expSum+=float(i)
    return expSum

def formatExp(exp):
    exp=exp.replace('--','+')
    exp=exp.replace('-+','-')
    exp=exp.replace('+-','-')
    exp=exp.replace('++','+')
    return exp

def calExp(exp):
    exp=mulDiv(exp)
    exp=formatExp(exp)
    expSum=addSub(exp)
    return expSum

def main(exp):
    exp=exp.replace(' ','').strip()
    while 1:
        bracket=re.search('\([^()]+\)',exp)
        if bracket:
            innerBracket=bracket.group()
            res=str(calExp(innerBracket))
            exp=exp.replace(innerBracket,res)
        else:
            return calExp(exp)

s='5 - 8 *  (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) '
res=main(s)
print(res)
print(eval(s))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值