zoukankan      html  css  js  c++  java
  • 基于re模块的计算器


    最终计算器需求:

    1. 实现加减乘除及拓号优先级解析
    2. 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式,运算后得出结果,结果必须与真实的计算器所得出的结果一致。

    a+b

    1 1 # 1.用于计算 a+b 的计算式。其中 a 和 b 是整数或者有限小数。没有空格和括号。没有其他四则计算。
    2 2 
    3 3 import re
    4 4 
    5 5 def addtion():
    6 6     formula = input("请输入一个公式(严格按照a+b)格式:")  # 得到一个公式字符串
    7 7     num_list = re.split("+",formula)  # 这里要注意,加号为元字符,前要加转义字符才行。结果得到一个列表 [a,b]
    8 8     return float(num_list[0]) + float(num_list[1])  # num_list[0] = "a" 是个字符。需要转成 float 类型
    9 9 print(addtion())

    a-b

    1 # 2.用于计算 a-b 的计算式。其中 a 和 b 是整数或者有限小数。没有空格和括号。没有其他四则计算。
    2 
    3 import re
    4 
    5 def addtion():
    6     formula = input("请输入一个公式(严格按照a-b)格式:")  # 得到一个公式字符串
    7     num_list = re.split("-",formula)  # 这里要注意,减号不是元字符。结果得到一个列表 [a,b]
    8     return float(num_list[0]) - float(num_list[1])  # num_list[0] = "a" 是个字符。需要转成 float 类型
    9 print(addtion())

     a+b 或 a-b

     1 # 3.用于计算 a-b 或者 a+b 的计算式。其中 a 和 b 是整数或者有限小数。没有空格和括号。没有其他四则计算。
     2 
     3 import re
     4 
     5 def addtion():
     6     formula = input("请输入一个公式(严格按照a+b或a-b)格式:")  # 得到一个公式字符串
     7     symbol = re.search("[-+]",formula).group()  # 此处serach得到的是个对象,需要调用group()方法,得到一个字符串。
     8     num_list = re.split("[-+]",formula)  # 不需要使用转义符号
     9     if symbol == "-":
    10         return float(num_list[0]) - float(num_list[1])  # num_list[0] = "a" 是个字符。需要转成 float 类型
    11         
    12     else:
    13         return float(num_list[0]) + float(num_list[1])  # num_list[0] = "a" 是个字符。需要转成 float 类型
    14 print(addtion())

    多位数加减(可带空格和 -  符号)比如 - 3 + 4 - 2

     1 def symbol_result(string):
     2     string = string.replace("++","+")
     3     string = string.replace("+-","-")
     4     string = string.replace("-+","-")
     5     string = string.replace("--","+")
     6     return string
     7 
     8 def addtion_reduce(s):        #处理加减法,变成数组,全加
     9     s = symbol_result(s)
    10     li = re.findall(r'([d.]+|+|-)', s)
    11     print (li)
    12     sum = 0
    13 
    14     for i in range(len(li)):
    15         # 碰到 - 符号,就把 - 变成 + ,后面那个数字取反
    16         if li[i] == '-':
    17             li[i] = '+'
    18             li[i+1] = float(li[i+1]) * (-1)
    19     for i in li:
    20         if i == '+':
    21             i = 0
    22         sum = sum + float(i)
    23     return str(sum)
    24 
    25 s = input("请输入公式:")
    26 addtion_reduce(s)
    多位数加减(带括号、负号)

     完整代码

    处理过程:

    1.当字符串传入后,先处理空格。用字符串方法 replace 处理。

    2.处理括号。循环条件,是否有 “(” 。如果有,表示还有括号。用 r'([^()]+)' 找到最里层括号,然后做计算。最终返回一个字符串。用这个字符串替换整个括号。

    3.计算部分分两块,乘除和加减。先做乘除,乘除用 r'[d.]+[*/]-?[d.]+' 找到一个字符串。要用 search 一个个处理,findall 太麻烦。找到字符串之后,以 * / 为 分界线,计算。

    4.加减 先处理 ++ +- -- 等问题,替换掉。然后把整个式子连同加减符号传入数组。把 - 变成 + ,后面那个元素取反。然后计算。

     1 import re
     2  
     3 def chengchu(s):          #处理带负号的乘除
     4     rRegex = re.compile(r"""
     5         [d.]+  # 表示 3 或者 2.2 这样的数字.
     6         [*/]     # 乘除必有
     7         -?       # 最关键的,有可能出现 (6*-3) 这种式子
     8         [d.]+  # 表示 3 或者 2.2 这样的数字.
     9                  # 连在一起就是 r'-?[d.]+[*/]-?[d.]+'
    10         """,re.VERBOSE) 
    11 
    12     while (("*" in s) or ("/" in s)):
    13         # 如果 "*" 或者 "/" 在字符串 s 中,表示还需要做乘除运算
    14 
    15         ma = rRegex.search(s).group()  # search 用 group 只找第一个
    16         li = re.split(r'[*/]', ma)  # ma 是一个式子,比如 -5.5*-5 。但是 while 里面 表示式子必定有 * 或者 /。以 * 或 / 为分隔符。
    17                                     #float 左右两个 -5.5 和 -5。然后做乘除就可以了。
    18         print(li,"li")
    19 
    20         if ("*") in ma:
    21             print(ma,"ma*")
    22             result = str(float(li[0]) * float(li[1]))
    23         else:
    24             print(ma,"ma/")
    25             result = str(float(li[0]) / float(li[1]))
    26         s = s.replace(ma, result, 1)
    27 
    28     return s
    29 
    30 def symbol_result(string):
    31     string = string.replace("++","+")
    32     string = string.replace("+-","-")
    33     string = string.replace("-+","-")
    34     string = string.replace("--","+")
    35     return string
    36 
    37 def jiajian(s):        #处理加减法,变成数组,全加
    38     s = symbol_result(s)
    39     li = re.findall(r'([d.]+|+|-)', s)
    40     print (li)
    41     sum = 0
    42 
    43     for i in range(len(li)):
    44         # 碰到 - 符号,就把 - 变成 + ,后面那个数字取反
    45         if li[i] == '-':
    46             li[i] = '+'
    47             li[i+1] = float(li[i+1]) * (-1)
    48     for i in li:
    49         if i == '+':
    50             i = 0
    51         sum = sum + float(i)
    52     return str(sum)
    53  
    54 def simple(s):  #处理不带括号的
    55     return jiajian(chengchu(s))
    56  
    57 def complex(s):  #处理带括号的
    58     while '(' in s: 
    59         #如果检测到还有括号
    60 
    61         # reg = re.compile(r'([^()]+)')  # 表示最里层的括号))
    62         ma = re.search(r'([^()]+)', s).group()  # 找到最里层括号内的字符串
    63         result = simple(ma[1:-1])  # 用切片去除括号,计算字符串
    64         s = s.replace(ma, result, 1)  # 把原先最里层括号字符串替换成计算结果
    65     return simple(s)
    66  
    67 ss = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'.replace(' ', '')
    68 # ss = "2*3*38*(2-3)".replace(" ","")
    69 print(complex(ss))
    70 print(eval(ss))
    完整代码
  • 相关阅读:
    Nuget 多平台多目标快速自动打包
    .Net Core 环境下构建强大且易用的规则引擎
    .Net 4.X 提前用上 .Net Core 的配置模式以及热重载配置
    [搬运] DotNetAnywhere:可供选择的 .NET 运行时
    [搬运] .NET Core 2.1中改进的堆栈信息
    [开源]OSharpNS 步步为营系列
    [开源]OSharpNS 步步为营系列
    [开源]OSharpNS 步步为营系列
    [开源]OSharpNS 步步为营系列
    [开源]OSharpNS 步步为营系列
  • 原文地址:https://www.cnblogs.com/dongye95/p/9002504.html
Copyright © 2011-2022 走看看