zoukankan      html  css  js  c++  java
  • 使用正则写一个计算器

    eval 不能直接计算数字表达式
    去掉s中的所有空格
    写正则表达式 把内部不再有括号的表达式提取出来
    写正则表达式 把a*b或者a/b这样的表达式从左到右依次匹配出来
    写正则表达式 把加减法匹配出来
    能够级匹配整数表达式 也匹配小数表达式

    如果 你已经拿到一个 a+b 或者 a*b
    写一个函数,计算这样表达式的结果
    '1+5'
    '1.345+2.567'
    s = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'

    import re
    s = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
    s = s.replace(' ','')
    
    def mul_di(num):
        if '/' in num:
            a,b = num.split('/')
            return str(float(a)/float(b))
        elif '*' in num:
            a,b = num.split('*')
            return str(float(a)*float(b))
    
    def mul_div(num):
        while True:
            mu = re.search('d+(.d+)?[*/]-?d+(.d+)?',num)
            if mu:
                mul = mu.group()
                mun = mul_di(mul)
                num = num.replace(mul,mun)
            else:break
        return num
    
    def cha_sym(num):
        num = num.replace('++','+')
        num = num.replace('+-','-')
        num = num.replace('-+','-')
        num = num.replace('--','+')
        return num
    def add_sub(num):
        nu = re.findall('[+-]?d+(?:.d+)?', num)
        count = 0
        for i in nu:
            count += float(i)
        return str(count)
    def no_sp(num):
        while True:
            nu = re.search('([^()]+)',num)
            if nu:
                ret = nu.group()
                Value = mul_div(ret)
                Value = cha_sym(Value)
                new_Value = add_sub(Value)
                num = num.replace(ret,new_Value)
            else:break
        ret = mul_div(num)
        Value = cha_sym(ret)
        return add_sub(Value)
    print(no_sp(s))

    递归做法

    import re
    def calculator(e,n=0,round_num=5):
        if ' ' in e:e = e.replace(' ','')
        regex_lst = ['(([d-+.*/])+)', '(d+.d+|d+)(*|/)(-?d+.d+|d+)', '(+|-){2,}','(-|+)?((d+.d+)|d+)']
        for step in range(n,len(regex_lst)):
            regex = re.compile(regex_lst[step])
            while 1:
                tmp = regex.finditer(e) if step==3 else regex.search(e)
                if not tmp:
                    if step==0:return None if ('(' in e or ')' in e) else round(calculator(e,1),round_num)
                    break
                if step == 3: return sum([float(i.group()) for i in tmp])
                dic = {0:lambda:calculator(tmp.group()[1:-1],1),
                       1:lambda:float(tmp.group(1))*float(tmp.group(3)) if '*' in tmp.group(2) else float(tmp.group(1))/float(tmp.group(3)),
                       2:lambda:'+' if tmp.group().count('-')%2==0 else '-'}
                e = e.replace(tmp.group(), str(dic[step]()))
    
    s1 = '1+(2-3-4*5/ (-4 - 2)+ 4 5 )-494+5+54+45*452-45245/4524*525-452-(56+45)'
    print(calculator(s1))
  • 相关阅读:
    openlayers跨域设置后出现http status 500错误
    myeclipse 2014 闪退问题解决
    html跨域获取数据
    centos的nginx支持ssl
    Hadoop学习笔记---HDFS
    Nginx Web服务器配置
    用ReentrantLock和Condition实现线程间通信
    Android绘图机制和处理技巧
    自定义ViewPagerIndicator-视图指示器
    Docker学习笔记
  • 原文地址:https://www.cnblogs.com/jiadi321/p/9302025.html
Copyright © 2011-2022 走看看