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实现360的字符显示界面
Feb 21 Python
python学习笔记:字典的使用示例详解
Jun 13 Python
Python argv用法详解
Jan 08 Python
Python简单格式化时间的方法【strftime函数】
Sep 18 Python
Python 网页解析HTMLParse的实例详解
Aug 10 Python
python实现梯度下降算法
Mar 24 Python
用Python解数独的方法示例
Oct 24 Python
Django使用rest_framework写出API
May 21 Python
浅谈Python中的字符串
Jun 10 Python
python3 sqlite3限制条件查询的操作
Apr 07 Python
如何用python反转图片,视频
Apr 24 Python
只用40行Python代码就能写出pdf转word小工具
May 31 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 4.2书写安全的脚本
2006/10/09 PHP
php编写的抽奖程序中奖概率算法
2015/05/14 PHP
PHP整合PayPal支付
2015/06/11 PHP
[原创]PHP实现逐行删除文件右侧空格的方法
2015/12/25 PHP
thinkphp3.2实现跨控制器调用其他模块的方法
2017/03/14 PHP
javascript阻止scroll事件多次执行的思路及实现
2013/11/08 Javascript
jquery用data方法获取某个元素上的事件
2014/06/23 Javascript
JavaScript中的原型和继承详解(图文)
2014/07/18 Javascript
js控制鼠标事件移动及移出效果显示
2014/10/19 Javascript
JavaScript实现打字效果的方法
2015/07/10 Javascript
基于jQuery实现动态搜索显示功能
2016/05/05 Javascript
vue2.0结合DataTable插件实现表格动态刷新的方法详解
2017/03/17 Javascript
Vue项目中引入外部文件的方法(css、js、less)
2017/07/24 Javascript
在Vue.js中使用Mixins的方法
2017/09/12 Javascript
浅谈Node.js爬虫之网页请求模块
2018/01/11 Javascript
vue二级路由设置方法
2018/02/09 Javascript
JS中的JSON对象的定义和取值实现代码
2018/05/09 Javascript
微信小程序实现红包功能(后端PHP实现逻辑)
2018/07/11 Javascript
Vue2.2.0+新特性整理及注意事项
2018/08/22 Javascript
vue基础之使用get、post、jsonp实现交互功能示例
2019/03/12 Javascript
express中static中间件的具体使用方法
2019/10/17 Javascript
解决Can't find variable: SockJS vue项目的问题
2020/09/22 Javascript
Python脚本实现DNSPod DNS动态解析域名
2015/02/14 Python
几个提升Python运行效率的方法之间的对比
2015/04/03 Python
Python爬虫使用脚本登录Github并查看信息
2018/07/16 Python
python numpy 反转 reverse示例
2019/12/04 Python
关于初始种子自动选取的区域生长实例(python+opencv)
2020/01/16 Python
Python3 shutil(高级文件操作模块)实例用法总结
2020/02/19 Python
python 调整图片亮度的示例
2020/12/03 Python
欧洲著名的珠宝和手表网上商城:uhrcenter
2017/04/10 全球购物
Linux如何修改文件和文件夹的权限
2012/06/27 面试题
活动宣传策划方案
2014/05/23 职场文书
单位单身证明样本
2014/10/11 职场文书
店铺转让协议书
2014/12/02 职场文书
2015年医院科室工作总结范文
2015/05/26 职场文书
javascript的setTimeout()使用方法总结
2021/11/20 Javascript