• 爱根,听闻根体欠安,吾茶饭不思夜不能寐,欲语泪先流!!!计算器!


     1 while True:
     2     s="0+%s"%input("please input you number str:").replace(" ","")
     3     print("------------------------%s"%eval(s))
     4     import re
     5     while True:
     6         a=re.search('([^()]+)',s)  #得到带括号的一个算式。
     7         if a !=None:    a=a.group()  #如果有返回值,说明有括号,那么再将a的所有值取出来group做成字符串。
     8         if a ==None:    a=s          #如果没有返回值,说明没有括号了,必须将返回的字符串进行计算。
     9         if len(re.findall("[+-]?d+.?d*",a))==1 and len(re.findall('([^()]+)',s))==0:#如果字符串中只有一个数字,而且没有(),
    10             print(s.replace("+",""))        #那么返回这个数字,说明已经得到了最终的结果。2776672.6951997154
    11             break                           #中断!
    12         if "/" in a:                        #优先查找/法。乘除前面的符号本来就是归于数字的,所以必须带上负号。
    13             b=re.search("(?P<fir>-?d+.?d*)/(?P<sec>[+-]?d+.?d*)",a) #将算式分组,成为两个数字。调用这两个数字进行运算。
    14             c=float(b.group("fir"))/float(b.group("sec")) #前面的匹配数字取负不取正,避免脱括号少减号,加+号会消加号,影响计算。
    15         elif "*" in a:             #其次是*法。  #而且避免连续出现三个符号,这样是为了约分。
    16             b=re.search("(?P<fir>-?d+.?d*)*(?P<sec>[+-]?d+.?d*)",a)  # 将算式分组,成为两个数字,实质也是约分,取负号。
    17             c=float(b.group("fir"))*float(b.group("sec"))  # 调用这两个数字进行运算。
    18         elif "+" or "-" in a:
    19             b=re.search("(?P<fir>[+-]*d+.?d*)(?P<sign>[+-]*)(?P<sec>d*.?d*)",a)#将算式分组成为两个数字,前面一个必须带符号。
    20             if b.group("sec") == "":                          #且去掉--,没用。
    21                 c = float(b.group("fir").replace("--","+"))   #如果sec是空的话,说明最原始输入的算式里面就一个数字,则不用再进行计算。
    22             elif b.group("sign") in ["+-","-","-+","+-+","++-"]: #评判符号,减号有五种情况,后两种是为了进行最前面0+的运算。
    23                 c=float(b.group("fir"))-float(b.group("sec"))  #调用这两个数字进行运算。
    24             else: c=float(b.group("fir"))+float(b.group("sec")) #其他的都是加法。
    25         if b.group("sec") != "" and float(b.group("fir"))<0 and float(b.group("sec"))<0: #这一步非常重要,如果前面的数字只有一个
    26             c="+%s" % (str(c))  #减号的话,会少个加号,但是上面匹配加减法的时候,一直是从左向右的,所以不必担心,第一个条件加上,避免报错。
    27         if len(re.findall("[+-]?d+.?d*",a))==2 or b.group("sec")=="": #如果括号内只剩余两个数字,或者输入的时候括号内就剩余一个
    28             s=s.replace(a, str(c),1) #数字那么就不用再计算了。将括号和括号内的算式替换计算结果。返回给s。括号为一体
    29             s=s.replace("(--","(",1) # ,其实不用加1。然后开始是两个“--”的时候,需要去掉,没用,影响计算。
    30         else:#如果括号内大于两个数字,就将算式替换为计算结果,因为search找到第一个匹配就返回,所以安全起见双重归一,replace也是只替换第一部分。
    31             s=s.replace(b.group(),str(c),1)   #将计算式替换为计算结果。返回给s,加1,双重归一,避免乱替换,有减号就麻烦了。
    32 # 思路:
    33 # 1、从最内层括号入手,按照-->*-->+的方法来进行计算,始终是两个数字在进行计算,直至将里面的算式全部计算完毕。
    34 # 2、替换时分为替换括号整体和算式,注意符号的转变,四则运算规则非常重要。
    35 # 3、弥补缺陷,就是 *  消符号的弊病,此版本输出地结果都带正负号,可以取结果引用再次作为参数。
    36 # 4、正则表达式利用search的特性,找到一个就返回值,可以轮番操这个括号内的内容,group的多元化应用。
    37 # 5、其实没有用到多少正则表达式的东西,呵呵,还好我又复习了一遍,不然转眼全忘了。
    38 #test=1 - 2 * ((60 - 30 + (-40 / 5) * (9 - 2 * 5 / 3 + 7 / 3 * 99 / 4 * 2998 + 10 * 568 / 14)) - (-4 * 3) / (16 - 3 * 2))
    39 #test1=--1-(+40)/(-5)-1/(+1)-(-3*3/-3+6/(+6))/(-1)*(-5)-(5)/(9)+(-3/7)
    40 #test2=-1-(+40)/(-5)-1/(+1)-(-3*3/-3+6/(+6)/(-1)*(-5)-(5))/(9)+(-3*7-(-4/2)/7)
    41 #test3=-(-5)/(+3)
    42 #test4=-(+5)/(-4)
    43 #test5=-(-1)
    44 #test6=(-(-5)/(+5))
    45 #test7=(--5)
  • 相关阅读:
    浅析深度优先和广度优先遍历实现过程、区别及使用场景
    浅析为什么要用setTimeout模拟setInterval
    app弹出软键盘获取键盘高度不准确的原因及导致底部定位的元素无法贴近键盘的问题
    App平台iOS设备上因内存不足导致白屏、闪退的原因及其解决方案
    浅谈移动端开发技术
    浅析Console命令调试常用方法
    js正则表达式中的正向肯定预查和正向否定预查, 反向肯定和反向否定(这个翻译不准确)
    javascript的版本查看及js的历史
    【转】JS-正则表达式的反向引用
    【转】Linux虚拟网络设备之tun/tap
  • 原文地址:https://www.cnblogs.com/chedanlangren/p/6784351.html
Copyright © 2020-2023  润新知