Python利用正则表达式实现计算器算法思路解析


Posted in Python onApril 25, 2018

(1)不使用eval()等系统自带的计算方法

(2)实现四则混合运算、括号优先级解析

思路:

1、字符串预处理,将所有空格去除

2、判断是否存在括号运算,若存在进行第3步,若不存在则直接进入第4步

3、利用正则表达式获取最底层括号内的四则运算表达式

4、将四则运算表达式进行预处理:表达式开头有负数时,在表达式前加上一个0

5、利用re.split()、re.findall()方法,通过加减符号,对四则运算进行拆分为乘除运算式和数字,并保留对应的位置下标。

6、利用re.split()、re.findall()方法,通过乘除符号,将乘除式拆分为乘除符号与数字,然后进行计算,并返回数值。

7、通过re.split()、re.findall()保留的下标位置,将表达式还原。

8、完成所有乘除运算之后,返回进行加减运算。

9、完成加减运算后,返回表达式进行替代。

10、通过递归函数,完成所有括号运算后。最后再完成一次四则运算即可完成所有运算。

注:在过程中,负数的处理存在三个要点:当负数出现在表达式开头、负数前面存在减法、乘除式中存在负数且不在表达式开头。

(1)当负数出现在表达式开头:在前面加上一个0

(2)负数前面存在减法:每次完成一次运算后需要进行一次符号检查替换

(3)乘除式中存在负数且不在表达式开头:将负号移到表达式最开头

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:Dang
import re
def update_formula(calc_list,calc_operator_list):
  # 通过拆分后的表达式列表与符号列表重新组合
  for index,item in enumerate(calc_list):
    if index == 0:
      formula = item
    elif index != 0:
      formula += calc_operator_list[index-1] + item
  return formula
def negative_start_issue(formula):
  #处理负数在括号内表达式开头的情形
  calc_list = re.split("[+-]",formula)  #通过+-符号将各个乘除运算分隔出来
  calc_operator_list = re.findall("[+-]",formula)
  for index,item in enumerate(calc_list):
    if index == 0 and item == '':  # 处理负号在开头的问题
      calc_list[index] = '0'
    else:
      calc_list[index] = item.strip()
  formula = update_formula(calc_list,calc_operator_list)
  return formula
def deal_unusual_issue(formula):
  # 双加减符号处理
  formula = formula.replace(" ","") #去掉空格
  formula = formula.replace("++","+")
  formula = formula.replace("+-", "-")
  formula = formula.replace("-+", "-")
  formula = formula.replace("--", "+")
  return formula
def deal_negative_issue(formula):
  # 处理乘除运算中负数的计算问题(分前后位置两种情况)
  # 1.负数在后
  m = re.search("[0-9]+[.]*[0-9]*[*|/][-][0-9]+[.]*[0-9]*",formula)
 # minus_pre = re.search("[0-9]+[.]*[0-9]*[*|/][-][0-9]+[.]*[0-9]*",formula).group()
  # 注意匹配的必要项与非必要项,如:"[0-9]+[.][0-9]+[*|/][-][0-9]+[.][0-9]+"误把非必要项当做必要项。
  if m:
    minus_pre = m.group()
    minus_pro = "-"+minus_pre.replace("-","")
    formula = formula.replace(minus_pre,minus_pro)
  if "*-" in formula or "/-" in formula:
    return deal_negative_issue(formula)
  # 2.负数在前
  formula = deal_unusual_issue(formula)
  return formula
def multiply_divide(formula):
  # print("[%s]"%formula,formula)
  # 乘除计算
  calc_list = re.split("[*/]", formula)
  operator_list = re.findall("[*/]", formula) # 将乘号除号通过列表方式分隔出来
  # print("sub_calc_list:", sub_calc_list)
  # print("sub_operator_list:", sub_operator_list)
  res = 0
  for index2, i in enumerate(calc_list):
    if index2 == 0:
      res = float(i)
    else:
      if operator_list[index2 - 1] == '*': # 通过sub_operator_list中的index判断到底是加法还是减法,
        res *= float(i)
      elif operator_list[index2 - 1] == '/':
        res /= float(i)
  return res
def add_abstract(formula):
  # 加减计算
  # 1.开头位置负数处理
  formula = negative_start_issue(formula)
  # 2.双加减符号处理
  formula = deal_unusual_issue(formula)
  # 3.加减逻辑运算
  calc_list = re.split("[+-]", formula)
  operator_list = re.findall("[+-]", formula)
  res = 0
  for index, i in enumerate(calc_list):
    if index == 0:
      res = float(i)
    else:
      if operator_list[index-1] == '+':
        res += float(i)
      elif operator_list[index-1] == '-':
        res -= float(i)
  return res
"""

四则混合运算主函数

"""def elementary_arithmetic(formula):
  # 负数处理
  formula = negative_start_issue(formula)
  formula = deal_negative_issue(formula)
  # 乘除运算
  calc_list = re.split("[+-]",formula)  # 通过+-符号将各个乘除运算分隔出来
  calc_operator_list = re.findall("[+-]",formula)
  for index1, item in enumerate(calc_list):
    calc_list[index1] = str(multiply_divide(item)) #数据类型的强制转换!!!
  formula = update_formula(calc_list,calc_operator_list)
  # 加减运算
  formula = add_abstract(formula)
  return formula
"""
括号运算
"""
def calculator(formula):
  #数据预处理
  formula = formula.replace(" ","")
  m = re.search("\([^()]*\)",formula)
  # 判断是否需要进行括号运算
  if m:
    # 括号运算
    # 提取最小括号运算式,计算结果,并返回。
    subformula = m.group().strip("()") # 把找出来的括号剥离
    print("subformula:",subformula,type(subformula))
    subres = elementary_arithmetic(subformula) # 调用四则混合运算主函数
    print("subres:",subres)
    formula = formula.replace(m.group(), str(subres))
    print("updated formula:",formula)
    if "(" in formula:
      return calculator(formula)
    else:
      print("formula result:",formula)
    # 除去所有括号后可能出现:1-2*-312.8
    formula = elementary_arithmetic(formula)
    return formula
  else:
    return elementary_arithmetic(formula)
# 以下为测试代码:
formula = "1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*9/4*28 +10 * 56/14 )) - (-4*3)/ (16-3*2) )"
print("%s = "%formula,calculator(formula))

总结

以上所述是小编给大家介绍的Python利用正则表达式实现计算器算法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
Python使用MONGODB入门实例
May 11 Python
在Django的模型中执行原始SQL查询的方法
Jul 21 Python
Python中的数据对象持久化存储模块pickle的使用示例
Mar 03 Python
利用python画一颗心的方法示例
Jan 31 Python
python之PyMongo使用总结
May 26 Python
详解Python中的正则表达式
Jul 08 Python
用python写一个定时提醒程序的实现代码
Jul 22 Python
使用python求解二次规划的问题
Feb 29 Python
python 数据分析实现长宽格式的转换
May 18 Python
pytorch 计算ConvTranspose1d输出特征大小方式
Jun 23 Python
PyCharm常用配置和常用插件(小结)
Feb 06 Python
python 基于DDT实现数据驱动测试
Feb 18 Python
Python实现随机生成手机号及正则验证手机号的方法
Apr 25 #Python
Python实现按中文排序的方法示例
Apr 25 #Python
Python实现的基于优先等级分配糖果问题算法示例
Apr 25 #Python
python自动登录12306并自动点击验证码完成登录的实现源代码
Apr 25 #Python
PyQt5实现拖放功能
Apr 25 #Python
wx.CheckBox创建复选框控件并响应鼠标点击事件
Apr 25 #Python
wxPython实现窗口用图片做背景
Apr 25 #Python
You might like
PHP 巧用数组降低程序的时间复杂度
2010/01/01 PHP
apache和PHP如何整合在一起
2015/10/12 PHP
php格式化时间戳
2016/12/17 PHP
thinkPHP5 ACL用户权限模块用法详解
2017/05/10 PHP
PHP 进程池与轮询调度算法实现多任务的示例代码
2019/11/26 PHP
基于jquery可配置循环左右滚动例子
2011/09/09 Javascript
jquery实现select下拉框美化特效代码分享
2015/08/18 Javascript
jquery实现图片上传前本地预览功能
2016/05/10 Javascript
JQuery为元素添加样式的实现方法
2016/07/20 Javascript
获取今天,昨天,本周,上周,本月,上月时间(实例分享)
2017/01/04 Javascript
JS组件系列之MVVM组件 vue 30分钟搞定前端增删改查
2017/04/28 Javascript
你可能不知道的前端算法之文字避让(inMap)
2018/01/12 Javascript
移动端H5页面返回并刷新页面(BFcache)的方法
2018/11/06 Javascript
Vue中的验证登录状态的实现方法
2019/03/09 Javascript
微信小程序开发注意指南和优化实践(小结)
2019/06/21 Javascript
Layui实现带查询条件的分页
2019/07/27 Javascript
node事件循环和process模块实例分析
2020/02/14 Javascript
vue 实现setInterval 创建和销毁实例
2020/07/21 Javascript
[01:18:21]EG vs TNC Supermajor小组赛B组败者组第一轮 BO3 第一场 6.2
2018/06/03 DOTA
[00:52]玛尔斯技能全介绍
2019/03/06 DOTA
Pyramid添加Middleware的方法实例
2013/11/27 Python
Python循环语句中else的用法总结
2016/09/11 Python
详解pyqt5 动画在QThread线程中无法运行问题
2018/05/05 Python
python指定写入文件时的编码格式方法
2018/06/07 Python
CentOS 7下安装Python3.6 及遇到的问题小结
2018/11/08 Python
Python使用pyserial进行串口通信的实例
2019/07/02 Python
Python如何使用k-means方法将列表中相似的句子归类
2019/08/08 Python
关于tf.TFRecordReader()函数的用法解析
2020/02/17 Python
Ralph Lauren英国官方网站:Ralph Lauren UK
2018/04/03 全球购物
Haglöfs瑞典官方网站:haglofs火柴棍,欧洲顶级户外品牌
2018/10/18 全球购物
创建精神文明单位实施方案
2014/03/08 职场文书
大学生党员自我评价范文
2014/04/09 职场文书
教师学期个人总结
2015/02/11 职场文书
雷锋的观后感
2015/06/10 职场文书
Java内存模型之happens-before概念详解
2021/06/13 Java/Android
python开发人人对战的五子棋小游戏
2022/05/02 Python