1.极限压缩版

  1. import re, functools
  2. def cal(formula):
  3. while re.search('(?:\d+\.?\d+|\d+)[+\-*/]', formula):
  4. while re.search('[*/]', formula): formula = re.sub('(?:\d+\.?\d+|\d+)[*/](?:\d+\.?\d+|\d+)', str(functools.reduce(lambda i, j: float(i) * float(j), re.search('(?:\d+\.?\d+|\d+)[*/](?:\d+\.?\d+|\d+)', formula).group().split('*')) if '*' in re.search('(?:\d+\.?\d+|\d+)[*/](?:\d+\.?\d+|\d+)', formula).group() else functools.reduce(lambda i, j: float(i) / float(j), re.search('(?:\d+\.?\d+|\d+)[*/](?:\d+\.?\d+|\d+)', formula).group().split('/'))), formula, 1)
  5. if re.search('(?:\d+\.?\d+|\d+)[+\-]', formula): formula = re.sub('-?(?:\d+\.?\d+|\d+)[+\-](?:\d+\.?\d+|\d+)', str(functools.reduce(lambda i, j: float(i) + float(j), re.search('-?(?:\d+\.?\d+|\d+)[+\-](?:\d+\.?\d+|\d+)', formula).group().rsplit('+', 1)) if '+' in re.search('(?:\d+\.?\d+|\d+)[+\-](?:\d+\.?\d+|\d+)', formula).group() else functools.reduce(lambda i, j: float(i) - float(j), re.search('-?(?:\d+\.?\d+|\d+)[+\-](?:\d+\.?\d+|\d+)', formula).group().rsplit('-', 1))), formula, 1)
  6. return formula
  7. formula = '1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'
  8. while re.search('\([^\(\)]+\)', formula):
  9. formula = re.sub('\([^\(\)]+\)', cal(re.search('\([^\(\)]+\)', re.sub('\s', '', formula)).group()).strip('()'), formula, 1)
  10. while re.search('[+\-*/]-', formula): formula = re.sub('[+]-', '-', formula) if '+-' in formula else re.sub('--', '', formula) if formula.startswith('--') else re.sub('(?:\d+\.?\d+|\d+)[*/]-', '-' + re.findall('(?:\d+\.?\d+|\d+)[*/](?=-)', formula)[0], formula) if re.search('[*/]-', formula) else re.sub('--', '+', formula)
  11. print(cal(formula).split('.0')[0] if cal(formula).endswith('.0') else cal(formula))

2.完整版

  1. import re
  2. from functools import reduce
  3.  
  4. def plus_minus(formula):
  5. '''
  6. 计算无括号的加减法算式
  7. :param formula: 等待计算的只包含加减法的字符串
  8. :return: 计算结果的字符串
  9. '''
  10. p1 = re.compile('-?(?:\d+\.?\d+|\d+)[+\-](?:\d+\.?\d+|\d+)') # 匹配一次加减法
  11. while re.search(p1, formula): # 每次计算一个二元加减,并替换到原字符串上,直到计算并计算完所有数
  12. x = re.search(p1, formula).group() # 匹配出一次计算,判断是加法还是减法,再由reduce把分割后的两个数交给匿名函数去计算。
  13. formula = re.sub(p1, str(reduce(lambda i, j: float(i) + float(j), x.rsplit('+', 1)) if '+' in x else reduce(lambda i, j: float(i) - float(j), x.rsplit('-', 1))), formula, 1)
  14. return formula
  15. # ps.计算加减法可以采用与乘除法不同的方式,可以把所有数全匹配出来再一起计算出来
  16.  
  17. def multi_divi(formula):
  18. '''
  19. 计算无括号的乘除法算式
  20. :param formula: 等待计算的只包含乘除法的字符串
  21. :return: 计算结果的字符串
  22. '''
  23. p = re.compile('(?:\d+\.?\d+|\d+)[*/](?:\d+\.?\d+|\d+)')
  24. while re.search(p, formula):
  25. y = re.search(p, formula).group()
  26. formula = re.sub(p, str(reduce(lambda i, j: float(i) * float(j), y.split('*')) if '*' in y else reduce(lambda i, j: float(i) / float(j), y.split('/'))), formula, 1)
  27. return formula
  28.  
  29. def parentheses_parse(formula):
  30. '''
  31. 用来处理括号,并调用加减乘除完成计算
  32. :param formula: 数学算式的字符串,支持加减乘除和括号
  33. :return: 最终结果的整型或浮点型
  34. '''
  35. formula = re.sub('\s', '', formula)
  36. p = re.compile('\([^\(\)]+\)') # 匹配内层括号
  37. while re.search(p, formula): # 循环到没有括号为止
  38. f = re.search(p, formula).group()
  39. formula = re.sub(p, plus_minus(multi_divi(f)).strip('()'), formula, 1) # 调用加减法嵌套乘除法,计算完括号内的式子,并去除括号
  40.  
  41. # 处理去除括号后可能出现的其他符号与负号相连的情况
  42. while re.search('[+\-*/]-', formula):
  43. formula = re.sub('[+]-', '-', formula)
  44. formula = re.sub('--', '', formula) if formula.startswith('--') else re.sub('--', '+', formula) # 正负为负,负负为正,并且避免正号出现在最前端
  45. if re.search('[*/]-', formula): # 遇到乘除连接负号的情况时,需要先把负号前置,再进行一次上面加减连接负号的处理
  46. n = re.search('(?:\d+\.?\d+|\d+)[*/](?=-)', formula).group() # 这里使用正向预匹配获得如'7*-'这样的序列中的'7*'的部分
  47. formula = re.sub('(?:\d+\.?\d+|\d+)[*/]-', '-' + n, formula) # 使用刚获得的字符串进行替换,来使‘7*-’变成‘-7*’的样子
  48. formula = plus_minus(multi_divi(formula)) # 没有括号了,再计算最后一次
  49. if formula.endswith('.0'): # 优化显示
  50. formula = int(formula.split('.0')[0])
  51. else:
  52. formula = float(formula)
  53. return formula
  54.  
  55. # 在此处输入算式
  56. print(parentheses_parse('1-2*((60- 30+(-40/5)*(9 -2*5/3+7/3*99/4*2998+1 0*568/14))-(-4*3)/(16-3*2))'))

3.思路清晰版

  1. import re
  2. from functools import reduce
  3.  
  4. def mul_div(exp):
  5. """
  6. 计算两个数的乘法或者除法
  7. :param exp:
  8. :return:
  9. """
  10. if '*' in exp:
  11. a, b = exp.split('*')
  12. return float(a)*float(b)
  13. if '/' in exp:
  14. a, b = exp.split('/')
  15. return float(a) / float(b)
  16.  
  17. def exp_fmt(exp):
  18. """
  19. 符号整理
  20. :param exp:
  21. :return:
  22. """
  23. while re.search('[+-]{2,}',exp):
  24. exp = exp.replace('--','+')
  25. exp = exp.replace('+-','-')
  26. exp = exp.replace('-+','-')
  27. exp = exp.replace('++','+')
  28. return exp
  29.  
  30. def remove_addsub(exp):
  31. """
  32. 计算两个数的加减法
  33. :param exp:
  34. :return:
  35. """
  36. ret = re.findall('[-+]?\d+(?:\.\d+)?',exp)
  37. res = reduce(lambda a,b:float(a)+float(b),ret)
  38. return res
  39.  
  40. def remove_muldiv(exp):
  41. """
  42. 计算表达式中的所有的乘除法
  43. :param exp:
  44. :return:
  45. """
  46. while True:
  47. ret = re.search('\d+(\.\d+)?[*/]-?\d+(\.\d+)?',exp)
  48. if ret:
  49. son_exp = ret.group()
  50. res = mul_div(son_exp)
  51. exp = exp.replace(son_exp,str(res))
  52. else:return exp
  53.  
  54. def cal(exp):
  55. res = remove_muldiv(exp) # 计算乘除
  56. res = exp_fmt(res) # 符号整理
  57. ret = remove_addsub(res) # 计算加减
  58. return ret
  59.  
  60. def main(exp):
  61. exp = exp.replace(' ','')
  62. while True:
  63. ret = re.search('\([^()]+\)', exp)
  64. if ret:
  65. res = cal(ret.group())
  66. exp = exp.replace(ret.group(), str(res))
  67. else: return cal(exp)
  68. exp = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
  69. ret = main(exp)
  70. print(ret)

待续

用Python代码写的计算器的更多相关文章

  1. [置顶] 如何用PYTHON代码写出音乐

    如何用PYTHON代码写出音乐 什么是MIDI 博主本人虽然五音不全,而且唱歌还很难听,但是还是非常喜欢听歌的.我一直在做这样的尝试,就是通过人工智能算法实现机器自动的作词和编曲(在这里预告下,通过深 ...

  2. python 之路,200行Python代码写了个打飞机游戏!

    早就知道pygame模块,就是没怎么深入研究过,恰逢这周未没约到妹子,只能自己在家玩自己啦,一时兴起,花了几个小时写了个打飞机程序. 很有意思,跟大家分享下. 先看一下项目结构 "" ...

  3. 如何用PYTHON代码写出音乐

    什么是MIDI 博主本人虽然五音不全,而且唱歌还很难听,但是还是非常喜欢听歌的.我一直在做这样的尝试,就是通过人工智能算法实现机器自动的作词和编曲(在这里预告下,通过深度学习写歌词已经实现了,之后会分 ...

  4. 10 行 Python 代码写的模糊查询

    导语: 模糊匹配可以算是现代编辑器(在选择要打开的文件时)的一个必备特性了,它所做的就是根据用户输入的部分内容,猜测用户想要的文件名,并提供一个推荐列表供用户选择. 样例如下: Vim (Ctrl-P ...

  5. 用 150 行 Python 代码写的量子计算模拟器

    简评:让你更轻松地明白,量子计算机如何遵循线性代数计算的. 这是个 GItHub 项目,可以简单了解一下. qusim.py 是一个多量子位的量子计算机模拟器(玩具?),用 150 行的 python ...

  6. 使用13行Python代码实现四则运算计算器函数

    原创的刷新行数记录的代码!!! 支持带小括号,支持多个连续+-号,如-7.9/(-1.2-++--99.3/-4.44)*---(2998.654+-+-+-(+1.3-7.654/(-1.36-99 ...

  7. (转)python 之路,200行Python代码写了个打飞机游戏!

    原文:https://www.cnblogs.com/alex3714/p/7966656.html

  8. 利用Python代码编写计算器小程序

    import tkinter import tkinter.messagebox import math class JSQ: def __init__(self): #创建主界面 self.root ...

  9. python代码如何写的优雅?

    简介 在实际项目中,我们可能一开始为了完成功能而忽视了代码的整体质量,因此,使用一些高阶的函数或方法,能够更加使我们的代码更加优雅.废话不多说,现在马上开始. 使用enumerate方法替代range ...

随机推荐

  1. CodeForces1006D-Two Strings Swaps

    D. Two Strings Swaps time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  2. HashMap的常见问题

    关于HashMap的一些常见的问题,自己总结一下: 首选HashMap在jdk1.7和jdk1.8里面的实现是不同的,在jdk1.7中HashMap的底层实现是通过数组+链表的形式实现的,在jdk1. ...

  3. eviews面板数据的操作

    数据结构: 打开eviews File>new>workfile Object>new object > pool 输入城市名称: _bj 下划线加名称(必须是英文),竖着输入 ...

  4. 通过Centreon监控apache、MySQL、Hadoop服务状态

    在上面的章节中,只是简单介绍了Centreon的几个基础监控项,例如添加主机.服务等,这些对于一个监控系统来说是远远不够的,本节将重点介绍对一些扩展服务的监控,也就是对一些常见应用的监控. 一. Na ...

  5. jwt Token验证与解析

    网上似乎没有相关代码 贴上一段Token的解析认证 [TestMethod] public void TestMethod1() { string Token = "eyJhbGciOiJI ...

  6. RequireJS 打包工具

    r.js是RequireJS的一个附产品,支持在 NodeJS环境下运行AMD程序,并且其包含了一个名为RequireJS Optimizer的工具,可以为项目完成合并脚本等优化操作 RequireJ ...

  7. Spring Boot 如何自定义返回错误码错误信息

    说明 在实际的开发过程中,很多时候要定义符合自己业务的错误码和错误信息,而不是统一的而不是统一的下面这种格式返回到调用端 INTERNAL_SERVER_ERROR(500, "Intern ...

  8. 多个datasource的配置与实现原理

          一般情况下,一个项目中只会有一个datasource,但是在某些情况.或者业务需求的情况下会出现一个项目有多个datasource的情况,当满足一定条件的时候,对数据库的操作就会从一个一个 ...

  9. TypeScript引入moment.js报错“无法找到moment模块”及解决方法

    npm i moment下载moment完成后,在ts文件中引入 import * as moment from "moment"; 结果疯狂报错,未找到moment模块. 一开始 ...

  10. 数百道BAT等大厂最新Python面试真题,学到你手软!

    春招临近,无论是要找工作的准毕业生,还是身在职场想要提升自己的程序员,提升自己的算法内功心法.提升 Python 编程能力,总是大有裨益的.今天,小编发现了一份好资源:Python 实现的面试题集锦! ...