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循环语句中else的用法总结
Sep 11 Python
python字典操作实例详解
Nov 16 Python
Python实现简易版的Web服务器(推荐)
Jan 29 Python
python实现向微信用户发送每日一句 python实现微信聊天机器人
Mar 27 Python
Python API 自动化实战详解(纯代码)
Jun 11 Python
Python集中化管理平台Ansible介绍与YAML简介
Jun 12 Python
Django REST Framework之频率限制的使用
Sep 29 Python
通过实例了解Python str()和repr()的区别
Jan 17 Python
tensorflow 实现打印pb模型的所有节点
Jan 23 Python
Python 字典中的所有方法及用法
Jun 10 Python
如何基于matlab相机标定导出xml文件
Nov 02 Python
Python request post上传文件常见要点
Nov 20 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将mysql数据库整库导出生成sql文件的具体实现
2014/01/08 PHP
PHP SPL标准库之数据结构堆(SplHeap)简单使用实例
2015/05/12 PHP
php基于Snoopy解析网页html的方法
2015/07/09 PHP
Yii统计不同类型邮箱数量的方法
2016/10/18 PHP
Javascript中产生固定结果的函数优化技巧
2013/01/16 Javascript
jquery删除提示框弹出是否删除对话框
2014/01/07 Javascript
extJS中常用的4种Ajax异步提交方式
2014/03/07 Javascript
JS嵌套函数调用上下文的问题解决
2014/03/26 Javascript
javascript实现控制浏览器全屏
2015/03/30 Javascript
纯javascript模仿微信打飞机小游戏
2015/08/20 Javascript
12个超实用的JQuery代码片段
2015/11/02 Javascript
小心!AngularJS结合RequireJS做文件合并压缩的那些坑
2016/01/09 Javascript
深入理解JQuery中的事件与动画
2016/05/18 Javascript
JS中常用的输出方式(五种)
2016/06/12 Javascript
slideToggle+slideup实现手机端折叠菜单效果
2017/05/25 Javascript
jQuery实现锚点向下平滑滚动特效示例
2017/08/29 jQuery
javascript实现点击产生随机图形
2021/01/25 Javascript
[02:33]2018 DOTA2亚洲邀请赛回顾视频 再次拾起那些美妙的时刻
2018/04/10 DOTA
详解duck typing鸭子类型程序设计与Python的实现示例
2016/06/03 Python
Python数据结构之栈、队列的实现代码分享
2017/12/04 Python
python函数式编程学习之yield表达式形式详解
2018/03/25 Python
python与C、C++混编的四种方式(小结)
2019/07/15 Python
Python3安装pip工具的详细步骤
2019/10/14 Python
利用python生成照片墙的示例代码
2020/04/09 Python
Python类的继承super相关原理解析
2020/10/22 Python
使用CSS3创建动态菜单效果
2015/07/10 HTML / CSS
开朗女孩的自我评价
2014/02/10 职场文书
酒店保安领班职务说明书
2014/03/04 职场文书
质量安全标语
2014/06/07 职场文书
汽修专业自荐信
2014/07/07 职场文书
南京南京观后感
2015/06/02 职场文书
舞出我人生观后感
2015/06/16 职场文书
党员干部学习三严三实心得体会
2016/01/05 职场文书
用position:sticky完美解决小程序吸顶问题的实现方法
2021/04/24 HTML / CSS
第四次工业革命,打工人与机器人的竞争
2022/04/21 数码科技
Python开发简易五子棋小游戏
2022/05/02 Python