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 相关文章推荐
c++生成dll使用python调用dll的方法
Jan 20 Python
python从sqlite读取并显示数据的方法
May 08 Python
python删除字符串中指定字符的方法
Aug 13 Python
python版本单链表实现代码
Sep 28 Python
python hook监听事件详解
Oct 25 Python
python实现弹窗祝福效果
Apr 07 Python
通过pycharm使用git的步骤(图文详解)
Jun 13 Python
Python super()函数使用及多重继承
May 06 Python
QML实现钟表效果
Jun 02 Python
浅谈sklearn中predict与predict_proba区别
Jun 28 Python
django跳转页面传参的实现
Sep 17 Python
改变 Python 中线程执行顺序的方法
Sep 24 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 文件缓存函数
2011/10/08 PHP
php fsockopen伪造post与get方法的详解
2013/06/14 PHP
PHP exif扩展方法开启详解
2014/07/28 PHP
PHP中IP地址与整型数字互相转换详解
2014/08/20 PHP
php正则匹配文章中的远程图片地址并下载图片至本地
2015/09/29 PHP
php的4种常用运行方式详解
2016/12/22 PHP
laravel框架数据库操作、查询构建器、Eloquent ORM操作实例分析
2019/12/20 PHP
Jquery从头学起第四讲 jquery入门教程
2010/08/01 Javascript
推荐30个新鲜出炉的精美 jQuery 效果
2012/03/26 Javascript
浅析onsubmit校验表单时利用ajax的return false无效问题
2013/07/10 Javascript
JQuery CheckBox(复选框)操作方法汇总
2015/04/15 Javascript
简介JavaScript中strike()方法的使用
2015/06/08 Javascript
一种Javascript解释ajax返回的json的好方法(推荐)
2016/06/02 Javascript
谈谈jQuery之Deferred源码剖析
2016/12/19 Javascript
ES6学习之变量的解构赋值
2017/02/12 Javascript
Node.JS中事件轮询(Event Loop)的解析
2017/02/25 Javascript
Bootstrap的popover(弹出框)在append后弹不出(失效)
2017/02/27 Javascript
jQuery实现分页功能(含ajax请求、后台数据、附完整demo)
2017/04/03 jQuery
AngularJS service之select下拉菜单效果
2017/07/28 Javascript
JQuery 选择器、DOM节点操作练习实例
2017/09/28 jQuery
jQuery动态添加li标签并添加属性和绑定事件方法
2018/02/24 jQuery
AngularJs1.x自定义指令独立作用域的函数传入参数方法
2018/10/09 Javascript
JS实现数组去重,显示重复元素及个数的方法示例
2019/01/21 Javascript
详解JavaScript 为什么要有 Symbol 类型?
2019/04/03 Javascript
详解Vue3.0 前的 TypeScript 最佳入门实践
2019/06/18 Javascript
[19:26]TNC vs EG (BO3)
2018/06/07 DOTA
Python中import导入不同目录的模块方法详解
2020/02/18 Python
win10安装python3.6的常见问题
2020/07/01 Python
Python如何定义接口和抽象类
2020/07/28 Python
python-地图可视化组件folium的操作
2020/12/14 Python
全网最详细的PyCharm+Anaconda的安装过程图解
2021/01/25 Python
css 元素选择器的简单实例
2016/05/23 HTML / CSS
基于HTML5实现类似微信手机摇一摇功能(计算摇动次数)
2017/07/24 HTML / CSS
农业生产宣传标语
2014/10/08 职场文书
2014年企业党建工作总结
2014/12/18 职场文书
评奖评优个人先进事迹材料
2015/11/04 职场文书