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实现的可以拷贝或剪切一个文件列表中的所有文件
Apr 30 Python
Python使用matplotlib绘制动画的方法
May 20 Python
python中利用Future对象异步返回结果示例代码
Sep 07 Python
python  创建一个保留重复值的列表的补码
Oct 15 Python
浅谈python3.6的tkinter运行问题
Feb 22 Python
django框架防止XSS注入的方法分析
Jun 21 Python
django重新生成数据库中的某张表方法
Aug 28 Python
TensorFlow实现打印每一层的输出
Jan 21 Python
Python 实现使用空值进行赋值 None
Mar 12 Python
Python基础数据类型tuple元组的概念与用法
Aug 02 Python
Python 恐龙跑跑小游戏实现流程
Feb 15 Python
Python pyecharts案例超市4年数据可视化分析
Aug 14 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 5.0对象模型深度探索之对象复制
2008/03/27 PHP
服务器web工具 php环境下
2010/12/29 PHP
php获取当月最后一天函数分享
2015/02/02 PHP
PHP Streams(流)详细介绍及使用
2015/05/12 PHP
验证坐标在某坐标区域内php代码
2016/10/08 PHP
PHP实现验证码校验功能
2017/11/16 PHP
PHP实现上传图片到数据库并显示输出的方法
2018/05/31 PHP
Javascript操纵Cookie实现购物车程序
2006/11/23 Javascript
用脚本调用样式的几种方法
2006/12/09 Javascript
javascript中的数字与字符串相加实例分析
2011/08/14 Javascript
jQuery 全选/反选以及单击行改变背景色实例
2013/07/02 Javascript
css+js实现部分区域高亮可编辑遮罩层
2014/03/04 Javascript
关闭时刷新父窗口两种方法
2014/05/07 Javascript
js表单验证实例讲解
2016/03/31 Javascript
js 获取站点应用名的简单实例
2016/08/18 Javascript
鼠标点击input,显示瞬间的边框颜色,对之修改与隐藏实例
2016/12/26 Javascript
详解javascript立即执行函数表达式IIFE
2017/02/13 Javascript
jQuery插件zTree实现删除树节点的方法示例
2017/03/08 Javascript
JS数组操作中的经典算法实例讲解
2017/07/26 Javascript
Angular 项目实现国际化的方法
2018/01/08 Javascript
JS运动改变单物体透明度的方法分析
2018/01/23 Javascript
浅谈Angular HttpClient简单入门
2018/05/04 Javascript
vue.js 实现点击按钮动态添加li的方法
2018/09/07 Javascript
[01:00:26]Ti4主赛事胜者组第一天 EG vs NEWBEE 1
2014/07/19 DOTA
Win8下python3.5.1安装教程
2020/07/29 Python
python生成九宫格图片
2018/11/19 Python
Django 表单模型选择框如何使用分组
2019/05/16 Python
Python拆分大型CSV文件代码实例
2019/10/07 Python
Django实现whoosh搜索引擎使用jieba分词
2020/04/08 Python
GC是什么?为什么要有GC?
2013/12/08 面试题
营销主管自我评价怎么写
2013/09/19 职场文书
2014年创先争优活动总结
2014/05/04 职场文书
设计顾问服务计划书
2014/05/04 职场文书
竞选纪律委员演讲稿
2014/09/13 职场文书
官僚主义现象查摆问题整改措施
2014/10/04 职场文书
2015年大学生社会实践评语
2015/03/26 职场文书