zoukankan      html  css  js  c++  java
  • 初版python计算器

    作业:

         使用正则表达式实现计算器功能。

     实现:

           1、实现带括号的计算

           2、实现指数、加减乘除求余等功能

    先看运行结果:

     1 请输入您的计算式: 1 - 2 * ( (60-30 +(-40.0/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) ) 
     2 第 1 选取的()为: ★(-40.0/5)★
     3      选取 乘除 运算第 1 运算式为:★40.0/5 4      乘除 运算第 1 运算式的结果为: ★-8.0 5 第 1 选取的()计算结果为: ★-8.0 6 新的表达式为: 1-2*((60-30-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))
     7 第 2 选取的()为: ★(9-2*5/3+7/3*99/4*2998+10*568/14)★
     8      选取 乘除 运算第 1 运算式为:★2*5 9      乘除 运算第 1 运算式的结果为: ★9-10.0/3+7/3*99/4*2998+10*568/1410      选取 乘除 运算第 2 运算式为:★10.0/311      乘除 运算第 2 运算式的结果为: ★9-3.3333+7/3*99/4*2998+10*568/1412      选取 乘除 运算第 3 运算式为:★7/313      乘除 运算第 3 运算式的结果为: ★9-3.3333+2.3333*99/4*2998+10*568/1414      选取 乘除 运算第 4 运算式为:★2.3333*9915      乘除 运算第 4 运算式的结果为: ★9-3.3333+230.9967/4*2998+10*568/1416      选取 乘除 运算第 5 运算式为:★230.9967/417      乘除 运算第 5 运算式的结果为: ★9-3.3333+57.7491*2998+10*568/1418      选取 乘除 运算第 6 运算式为:★57.7491*299819      乘除 运算第 6 运算式的结果为: ★9-3.3333+173131.8018+10*568/1420      选取 乘除 运算第 7 运算式为:★10*56821      乘除 运算第 7 运算式的结果为: ★9-3.3333+173131.8018+5680.0/1422      选取 乘除 运算第 8 运算式为:★5680.0/1423      乘除 运算第 8 运算式的结果为: ★9-3.3333+173131.8018+405.714224      选取 加减 运算第 1 运算式为:★9-3.333325      加减 运算第 1 运算式的结果为: ★5.6667+173131.8018+405.714226      选取 加减 运算第 2 运算式为:★5.6667+173131.801827      加减 运算第 2 运算式的结果为: ★173137.4685+405.714228      选取 加减 运算第 3 运算式为:★173137.4685+405.714229      加减 运算第 3 运算式的结果为: ★173543.182630 第 2 选取的()计算结果为: ★173543.182631 新的表达式为: 1-2*((60-30-8.0*173543.1826)-(-4*3)/(16-3*2))
    32 第 3 选取的()为: ★(60-30-8.0*173543.1826)★
    33      选取 乘除 运算第 1 运算式为:★8.0*173543.182634      乘除 运算第 1 运算式的结果为: ★60-30-1388345.460835      选取 加减 运算第 1 运算式为:★60-3036      加减 运算第 1 运算式的结果为: ★30.0-1388345.460837      选取 加减 运算第 2 运算式为:★30.0-1388345.460838      加减 运算第 2 运算式的结果为: ★-1388315.460839 第 3 选取的()计算结果为: ★-1388315.460840 新的表达式为: 1-2*(-1388315.4608-(-4*3)/(16-3*2))
    41 第 4 选取的()为: ★(-4*3)★
    42      选取 乘除 运算第 1 运算式为:★4*343      乘除 运算第 1 运算式的结果为: ★-12.044 第 4 选取的()计算结果为: ★-12.045 新的表达式为: 1-2*(-1388315.4608+12.0/(16-3*2))
    46 第 5 选取的()为: ★(16-3*2)★
    47      选取 乘除 运算第 1 运算式为:★3*248      乘除 运算第 1 运算式的结果为: ★16-6.049      选取 加减 运算第 1 运算式为:★16-6.050      加减 运算第 1 运算式的结果为: ★10.051 第 5 选取的()计算结果为: ★10.052 新的表达式为: 1-2*(-1388315.4608+12.0/10.0)
    53 第 6 选取的()为: ★(-1388315.4608+12.0/10.0)★
    54      选取 乘除 运算第 1 运算式为:★12.0/10.055      乘除 运算第 1 运算式的结果为: ★-1388315.4608+1.256      选取 加减 运算第 1 运算式为:★-1388315.4608+1.257      加减 运算第 1 运算式的结果为: ★-1388314.260858 第 6 选取的()计算结果为: ★-1388314.260859 新的表达式为: 1-2*-1388314.2608
    60 ()选择结束,执行如上最后计算式
    61      选取 乘除 运算第 1 运算式为:★2*-1388314.260862      乘除 运算第 1 运算式的结果为: ★1+2776628.521663      选取 加减 运算第 1 运算式为:★1+2776628.521664      加减 运算第 1 运算式的结果为: ★2776629.521665 最后的计算结果为: ★2776629.5216★
    运行结果

    大致思路:

    1、匹配模块:

    循环匹配最内部括号,匹配后计算结果并替换原字符串

    2、计算模块:

    循环匹配乘除运算、匹配后计算结果并替换

    循环匹配加减运算、匹配后计算结果并替换

    3、里面有很多细节要注意如:

    检测非法输入、保留四位小数、-号的处理原则等。

    源码如下:

      1 import re
      2 welcome = '''
      3 -------------------------------------
      4     welcome to the counter of lmh
      5 -------------------------------------
      6 '''
      7 def format_s(x): #格式化输出
      8     x = re.sub(r'\s+','',x)
      9     x = re.sub(r'\++|\-\-',r'+',x)
     10     x = re.sub(r'\-\+|\+\-',r'-',x)
     11     x = re.sub(r'\.+',r'.',x)
     12     while True:
     13         x1 = re.search(r'\d+\.\d{5}',x)
     14         if x1 == None:
     15             break
     16         else:
     17             x2 = re.search(r'\d+\.\d{4}',x1.group())
     18             x = re.sub(r'\d+\.\d{5,}',x2.group(),x,1)
     19     return x
     20 
     21 def islegal(x): #判断输入是否合法
     22     global flag
     23     flag = 0
     24     ret0 = re.search('\.\d+\..*',x)
     25     ret = re.sub(r'\d|\+|\-|\*|\/|\(|\)|\s+|\.+','',x)
     26     if ret0 ==None and ret == '':
     27         pass
     28     else:
     29         print('您的输入不合法请重新输入')
     30         flag = 1
     31 
     32 def cal_num(x):   #二元计算式算法,x为需要处理的二元字符串
     33     ss = re.search('\D',x)
     34     if ss == None:
     35         return x
     36     else:
     37         s1 = float(re.search('^\-*\d+\.?\d*',x).group()) #选取元素x
     38         s2 = float(re.search('\-*\d+\.?\d*$',x).group()) #选取元素y
     39         sb = re.search(r'\*',x)  #匹配二元计算式是否包含元素*
     40         sb2 = re.search(r'/',x)  #匹配二元计算式是否包含元素/
     41         sb3 = re.search(r'\+',x) #匹配二元计算式是否包含是否元素+,前面已经格式化。有+号代表选取的二元计算式只能是+法运算
     42         sb4 = re.search('\-*\d+\.?\d*\-\-*\d+\.?\d*',x) #选取元素- 注意:第一个元素可能有负号,因此需要选取左右都为数字的
     43         if sb != None:
     44             s4 = float(s1) * float(s2)
     45         elif sb2 != None:
     46             s4 = float(s1) / float(s2)
     47         elif sb3 != None:
     48             s4 = float(s1) + float(s2)
     49         elif sb4 != None:
     50             s4 = float(s1) + float(s2)
     51         else:
     52             s4 = float(s1)
     53         s5 = str(s4)
     54         return s5
     55 
     56 def cal_select(p):#先乘除后加减方法
     57     d = '乘除'
     58     first = re.compile(r'\d+\.*\d*\*\-*\d+\.*\d*|\d+\.*\d*/\-*\d+\.*\d*')#匹配*号或者/前面的数字和后面的数字。注意:前面不匹配-号,后面需要匹配-号
     59     second = re.compile(r'\-*\d+\.*\d*\+\-*\d+\.*\d*|\-*\d+\.*\d*\-\-*\d+\.*\d*')#匹配+号前面的数字和后面的数字。注意:前面匹配-号,后面也需要匹配-号
     60     def cir(x):
     61         i = 1
     62         while True:
     63             nonlocal p
     64             s0 = x.search(p)  #选取第一个2元计算式
     65             if s0 == None:
     66                 break
     67             s0 = s0.group()
     68             print('     选取 %s 运算第 %s 运算式为:★%s★'%(d,i,s0))
     69             p = re.sub(x, cal_num(s0), p,count=1)
     70             p = format_s(p)
     71             print('     %s 运算第 %s 运算式的结果为: ★%s★'%(d,i,p))
     72             i += 1
     73     cir(first)
     74     d = '加减'
     75     cir(second)
     76     p = format_s(p)
     77     return p
     78 
     79 while True:#判断输入合法性
     80     print(welcome)
     81     s = input(r'请输入您的计算式: ')
     82     islegal(s)
     83     if flag == 1:
     84         continue
     85     else:
     86         break
     87 s = format_s(s)
     88 
     89 i=1
     90 while True:#依次匹配最内部()
     91     find_parentheses = re.compile(r'\([^()]*\)')  #匹配最内部(..)方法
     92     clear_parentheses = re.compile('\(|\)')        #只匹配()方法
     93     ret = find_parentheses.search(s) #匹配字符串s最内部括号
     94     if ret == None:
     95         break
     96     s0 = clear_parentheses.sub('',ret.group())  #取消字符串s最内部括号,保留内部计算式s0
     97     print('第 %s 选取的()为: ★%s★'%(i,ret.group()))
     98     s5 = cal_select(s0) #计算s0结果
     99     print('第 %s 选取的()计算结果为: ★%s★'%(i,s5))
    100     s = re.sub(find_parentheses,s5,s,count=1) #替换在s字符串中替换so
    101     s = format_s(s) #刷新格式
    102     print('新的表达式为: %s'%s)
    103     i += 1
    104 
    105 print('()选择结束,执行如上最后计算式')
    106 s = cal_select(s)
    107 print('最后的计算结果为: ★%s★'%s)
    counter
  • 相关阅读:
    isNUll ,对于sql中的一个表的description的NULL和空格的处理
    Thread类学习
    java学习计划
    HTTP请求过程(http是一种无状态协议,即不建立持久的连接)
    JS事件流(W3C与IE区别)
    学习Javascript闭包
    div内长串数字或字母不断行处理
    仿购物车加减数字
    多行文字两行断尾点点点显示
    MegaCli命令详解
  • 原文地址:https://www.cnblogs.com/testlmh/p/8513959.html
Copyright © 2011-2022 走看看