zoukankan      html  css  js  c++  java
  • python基础篇14-计算器练习

    要求:

    # 实现加减乘除及拓号优先级解析
    # 用户输入 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 #__author: lriwu
      2 #date 2018/1/30
      3 
      4 # 实现加减乘除及拓号优先级解析
      5 # 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )
      6 # 等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式(不能调用eval等类似功能偷懒实现),运算后得出结果,
      7 # 结果必须与真实的计算器所得出的结果一致
      8 
      9 import re
     10 
     11 def check_expression(string):
     12     ckeck_result = True
     13     #检查括号是否匹配
     14     if not string.count('(') == string.count(')'):
     15         print("表达式错误,括号未闭合")
     16         ckeck_result = False
     17     if re.findall('[a-z]+',string.lower()):
     18         print("表达式错误,含非法字符")
     19         ckeck_result = False
     20 
     21     return ckeck_result
     22 
     23 
     24 def format_string(string):
     25     string = string.replace(' ','')
     26     string = string.replace('+-','-')
     27     string = string.replace('-+', '-')
     28     string = string.replace('++', '+')
     29     string = string.replace('--', '+')
     30     string = string.replace('*+', '*')
     31     string = string.replace('/+', '/')
     32     return string
     33 
     34 def calc_mul_div(string):
     35     # 从字符串中获取乘除表达式  (-3.1*-2.1+1-2*3)
     36     regular = 'd+.?d*([*/]|**)[-]?d+.?d*'
     37     #如果还能找到乘或除表达式
     38     while re.findall(regular,string):
     39         #获取表达式
     40         expression = re.search(regular,string).group()
     41 
     42         #如果时乘法
     43         if expression.count('*') == 1:
     44             #获取要计算的两个数
     45             x,y = expression.split('*')
     46             #计算结果
     47             mul_result = str(float(x) * float(y))
     48             #将计算的表达式替换为计算的结果值
     49             string = string.replace(expression,mul_result)
     50             string = format_string(string)
     51 
     52         # 如果时除法
     53         if '/' in expression:
     54             # 获取要计算的两个数
     55             x, y = expression.split('/')
     56             # 计算结果
     57             mul_result = str(float(x) / float(y))
     58             # 将计算的表达式替换为计算的结果值
     59             string = string.replace(expression, mul_result)
     60             string = format_string(string)
     61 
     62     return string
     63 
     64 
     65 def calc_add_sub(string):  #(-2.1+2.1-1+2)
     66     #定义正则表达式
     67     add_regular = '-?d+.?d*+-?d+.?d*'
     68     sub_regular = '-?d+.?d*--?d+.?d*'
     69     # 从字符串中获取加减表达式
     70     # 计算加法
     71     while re.findall(add_regular, string):
     72         # 获取表达式
     73         add_list = re.findall(add_regular, string)
     74         for add_str in add_list:
     75             #获取两个加法的数
     76             x,y = add_str.split('+')
     77             add_result = '+'+str(float(x) + float(y))
     78             string = string.replace(add_str,add_result)
     79         string = format_string(string)
     80 
     81     #计算减法
     82     while re.findall(sub_regular, string):
     83         # 获取表达式
     84         sub_list = re.findall(sub_regular, string)
     85         for sub_str in sub_list:
     86             #获取两个减法的数
     87             members = sub_str.split('-')
     88             if len(members) == 3:
     89                 sub_result = 0
     90                 for v in members:
     91                     sub_result -= float(sub_result)  #sub_result = sub_result -float(sub_result)
     92 
     93             else:
     94                 x,y = members
     95                 sub_result = float(x) - float(y)
     96 
     97             string = string.replace(sub_str, "+"+str(sub_result))
     98         string = format_string(string)
     99     return string
    100 
    101 
    102 
    103 
    104 
    105 
    106 
    107 
    108 
    109 
    110 
    111 
    112 
    113 
    114 
    115 
    116 if __name__ == '__main__':
    117     source = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
    118     if check_expression(source):
    119         print("source:",source)
    120         print("eval result:",eval(source))
    121         source = format_string(source)
    122         print(source)
    123 
    124         while source.count('(') > 0:
    125             strs = re.search('([^()]+)',source).group() #['(-40/5)', '(9-2*5/3+7/3*99/4*2998+10*568/14)', '(-4*3)', '(16-3*2)']
    126             #将括号的表达式进行乘除运算
    127             replace_str = calc_mul_div(strs)
    128 
    129             #将括号的表达式进行加减运算
    130             replace_str = calc_add_sub(replace_str)
    131 
    132             #将括号的字符串替换为计算结果,结果包含括号(),替换时去掉括号():[1:-1]
    133             source = format_string(source.replace(strs,replace_str[1:-1]))
    134         #没有括号就到最后单一表达式了
    135         else:
    136             #算乘除
    137             replace_str = calc_mul_div(source)
    138             #算加减
    139             replace_str = calc_add_sub(replace_str)
    140             source = source.replace(source,replace_str)
    141             #source = source.replace(source, replace_str))
    142 
    143         print(source)
  • 相关阅读:
    HTML---网页编程(2)
    HTML---网页编程(1)
    HDOJ/HDU 1297 Children’s Queue(推导~大数)
    HDOJ/HDU 1250 Hat's Fibonacci(大数~斐波拉契)
    HDOJ/HDU 1133 Buy the Ticket(数论~卡特兰数~大数~)
    洛谷P1314 [NOIP2011提高组Day2T2] 聪明的质监员
    洛谷P1313 [NOIP2011提高组Day2T1]计算系数
    POJ3696 The Luckiest number
    洛谷P1312 [NOIP2011提高组Day1T3]Mayan游戏
    洛谷P1311 [NOIP2011提高组Day1T2]选择客栈
  • 原文地址:https://www.cnblogs.com/lriwu/p/8387412.html
Copyright © 2011-2022 走看看