侯体宗的博客
  • 首页
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

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

Python  /  管理员 发布于 7年前   207

  (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:Dangimport redef 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 formuladef 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 formuladef deal_unusual_issue(formula):  # 双加减符号处理  formula = formula.replace(" ","") #去掉空格  formula = formula.replace("++","+")  formula = formula.replace("+-", "-")  formula = formula.replace("-+", "-")  formula = formula.replace("--", "+")  return formuladef 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 formuladef 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 resdef 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 email smtplib模块发送邮件代码实例
    下一条:
    Python实现随机生成手机号及正则验证手机号的方法
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(95个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客