目的:实现同Python中eval函数一样,对于复杂算术运算提供一个简易的计算器;

思路:

1、通过正则表达式,将运算式子中所有的数字和运算符分割开来形成类表的方式,然后可以方便列表检索进行运算,eq_format(eq)函数;

2、通过列表的检索,通过递归的运算,一层层的剥离掉(),然后进行+,-,*,/,最终得到完全没有括号的算式,进行最后一步的运算,期间需要处理+-,–的情况出现,主要涉及到change(eq,count)函数;

(对于()剥离的情况,主要是通过遍历列表,如果遇到左括号,则把当前左括号的索引赋值给参数bracket,直到遇到第一个右括号,此时的索引与bracket中间的元素即为最内层括号的元素,用切片的方式提取出来,通过 calculate() 函数计算出值,然后用计算结果去替换掉此时左括号到第一个右括号的元素,此时去除第一层括号,然后进入递归,不断递归直至去除所有括号;

可能遇到的问题:

不要用index的方式去取当前左括号的索引,因为列表的index方法返回的一直都是第一个左括号的索引,而不是当前左括号的索引,会导致出错。因此在函数内用参数 自定义的参数count 进行计数当前索引值。用计算得出的值来替换掉第一层括号部分后,有可能会出现 ‘+-’ ,‘ - -’的情况,然后用change() 函数进行处理)

3、去括号的方式,主要是从最内层开始突破,通过运算得到结果替换掉(),然后一层层向外运算剥离,最后得到结果,主要是simplify(format_list)函数中嵌套change()函数和calculate()函数进行运算取括号以及特殊处理;

4、对于乘除的运算详见deal_multiplication_division()函数部分,方法也是递归,处理掉一层乘除以后得到的结果进行判断处理掉+-,–的情况,然后进入下一步运算,其中嵌套change(eq,count)函数来进行特殊处理;

5、对于加减的运算详见deal_plus_minus()函数部分,方法同样是递归;

6、整体运算的过程主要是calculate(s_eq)函数,通过判断是加减还是乘除的方式嵌套deal_multiplication_division()函数和deal_plus_minus()函数,然后嵌套在simplify()函数当中进行运算;

7、最后使用calculator(eq)主函数,嵌套simplify()和calculate()函数进行最后的计算得到结果;

详细代码如下:

import re

def eq_format(eq): #格式化计算式函数

'''

:param eq:输入的算术字符串

:return: 格式化后的列表,例如['-','2','+','3','*','12','/','123']

'''

format_list = re.findall('[\d\.]+|\(|\+|\-|\*|\/|\)',eq)

#print(format_list) '[\d\.]+|\(|\+|\-|\*|\/|\)'

return format_list #返回格式化的列表形式内容

def change(eq,count): #解决同时出现+-,--类的格式化列表

'''

:param eq:去掉括号以后或者乘除后的格式化列表

:param count: 发生变化的元素的索引位置

:return: 返回一个没有+-,--等类的格式化列表内容

'''

if eq[count] == '-': #如果第count元素是-的话

if eq[count-1] == '-': #且第count-1元素也是-

eq[count-1] = '+' #那么调整count-1元素为+

del eq[count] #删除第count元素内容

elif eq[count-1] == '+':

eq[count-1] = '-'

del eq[count]

return eq

def deal_multiplication_division(eq): #处理所有的乘除的计算方程式

'''

:param eq:处理带有乘除符号的格式化列表

:return: 去掉乘除好以后的格式化列表

'''

count = 0

for i in eq:

if i == '*':

if eq[count+1] != '-':

eq[count-1] = float(eq[count-1]) * float(eq[count+1])

del(eq[count])

del(eq[count])

elif eq[count+1] == '-':

eq[count] = float(eq[count-1]) * float(eq[count+2])

eq[count - 1] = '-'

del(eq[count+1])

del(eq[count+1])

eq = change(eq,count-1)

return deal_multiplication_division(eq)

elif i == '/':

if eq[count+1] != '-':

eq[count-1] = float(eq[count-1]) / float(eq[count+1])

del(eq[count])

del(eq[count])

elif eq[count+1] == '-':

eq[count] = float(eq[count-1]) / float(eq[count+2])

eq[count-1] = '-'

del(eq[count+1])

del(eq[count+1])

eq = change(eq,count-1)

return deal_multiplication_division(eq)

count = count + 1

return eq

def deal_plus_minus(eq): #处理所有的加减方程式的计算

'''

:param eq:只带有加减号的格式化列表

:return: 计算出整个列表的结果

'''

count = 0

if eq[0] != '-':

sum = float(eq[0])

else:

sum = 0.0

for i in eq:

if i == '-':

sum = sum - float(eq[count+1])

elif i == '+':

sum = sum + float(eq[count+1])

count = count + 1

if sum >= 0:

eq = [str(sum)]

else:

eq = ['-',str(-sum)]

return eq

def calculate(s_eq): #处理进行加减乘除

'''

:param s_eq:不带括号的格式化列表

:return: 返回最终的计算结果

'''

if '*' or '/' in s_eq:

s_eq = deal_multiplication_division(s_eq)

if '+' or '-' in s_eq:

s_eq = deal_plus_minus(s_eq)

return s_eq

def simplify(format_list): #递归方式去掉括号,并计算到最后一层没有括号

'''

:param format_list:输入的算是格式化列表如['-','2','+','3','*','12','/','123']

:return:通过递归去掉括号,返回最终简化后没有括号的列表

'''

bracket = 0 #用于存放左括号在格式化列表中的索引

count = 0

for i in format_list:

if i == '(':

bracket = count

elif i == ')':

temp = format_list[bracket + 1 : count]

new_temp = calculate(temp)

format_list = format_list[:bracket] + new_temp + format_list[count+1:]

format_list = change(format_list,bracket) #解决去括号后出现的'--','+-'问题

return simplify(format_list) #递归去掉括号

count = count + 1

return format_list #当递归到最后一层层的时候,不在有括号,因此返回最后无括号的列表内容

def calculator(eq): #计算主函数,主要判断最终计算结果的正负值,并返回

format_list = eq_format(eq) # 把字符串变成格式化的列表形式

s_eq = simplify(format_list) #去掉括号,得到一个无括号的格式化列表

ans = calculate(s_eq) #计算最终结果

if len(ans) == 2: #判断最终结果的正负值并返回结果

ans = -float(ans[1])

else:

ans = float(ans[0])

return ans #返回最终的结果

if __name__ == '__main__':

equation = '1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'

ans = calculator(equation)

print('eval运算结果:',eval(equation))

print('程序运算结果:',ans)

参考链接:

link

python加减乘除计算器 eval_Python计算器(模拟eval)相关推荐

  1. python中float与eval式一样的吗_用Python最原始的函数模拟eval函数的浮点数运算功能...

    前几天看一个网友提问,如何计算'1+1'这种字符串的值,不能用eval函数. 我仿佛记得以前新手时,对这个问题完全不知道如何下手. 我觉得处理括号实在是太复杂了,多层嵌套括号怎么解析呢?一些多余的括号 ...

  2. python妙用桌面计算器

    python当计算器--不是玩笑 python是一个好东西 度娘说: Python由荷兰数学和计算机科学研究学会的Guido van Rossum 于1990 年代初设计,作为一门叫做ABC语言的替代 ...

  3. python材料计算程序_把python当日常的”计算器”用

    把python当日常的"计算器"用 作为程序员,常常看见其他的程序员在windows下打开程序/附件/计算器,觉得很不可思议,我们 有很多好用的东西可替代. 随便装一个动态语言在命 ...

  4. python做的简单gui计算器_Python计算器–使用Tkinter创建一个简单的GUI计算器

    在Python计算器教程中,您将学习创建简单的GUI计算器.在这篇文章中,我将向您展示如何使用python中的tkinter模块开发一个简单的计算器.因此,让我们进一步创建一个简单的python计算器 ...

  5. 利用android实现汇率计算器,利用python编写一个汇率计算器

    利用python编写一个汇率计算器 发布时间:2020-11-10 15:03:44 来源:亿速云 阅读:137 作者:Leah 这篇文章运用简单易懂的例子给大家介绍利用python编写一个汇率计算器 ...

  6. python银行利息问题_python入门教程NO.8 用python写个存款利息计算器

    python入门教程 python入门教程NO.8 用python写个存款利息计算器 本文涉及的python基础语法为def函数,return,函数的各参数示例,匿名函数等 函数初识 函数是一段组织好 ...

  7. [ Java ] 实现两个数加减乘除的简易计算器

    [ Java ] 实现两个数加减乘除的简易计算器 新手,不足之处望大佬们海涵 感谢( *ˊᵕˋ)✩︎‧₊ 以下为代码: package com.zhong.homework;import java.u ...

  8. Java:利用工厂模式设计加减乘除功能的计算器

    使用简单工厂模式开发一个包含加减乘除功能的计算器. 思路如下: 1.构造一个计算器抽象类:属性:含有两个参与计算的数字:方法:获取返回计算结果. 2.创建加法.减法.乘法.除法功能子类,继承计算器,在 ...

  9. python存款模块_python入门教程NO.8用python写个存款利息计算器

    python 入门教程 NO.8 用 python 写个存款利息计算器 本文涉及的 python 基础语法为 def 函数, return ,函数的各参数示例,匿名函数等 函数初识 函数是一段组织好的 ...

  10. python:实现杂货计算器grocery calculator(附完整源码)

    python:实现杂货计算器grocery calculator class GroceryList(dict):def __init__(self):self = {}def addToList(s ...

最新文章

  1. 计算机软件属于输入还是输出,计算机基本输入输出系统是什么意思(基本输入输出系统简介)...
  2. 研究院引进:博士70万;硕士40万
  3. RadioGroup结合RadioButton使用切换Fragment片段
  4. ML之FE:特征工程之数据处理常用案例总结(数值型数据处理、类别型数据处理)及其代码实现
  5. 数据库建立索引、数据表创建规则、备用字段 / 保留字段 / 预留字段
  6. mailbox 编程_往死里写——从站mailbox实现 | 学步园
  7. 地图上如何量方位角_楼承板厂家揭秘:压型钢板采购的7个坑之第2个坑_压型钢板如何在镀锌量上偷工减料?...
  8. crossorigin注解添加了解决不了跨域问题_springboot 处理跨域的2种方式
  9. 桶排序/基数排序(Radix Sort)
  10. 注册表删除计算机用户密码,修改注册表删除WIN10开机密码
  11. 10个WEB设计戒律 和 10个设计师戒律
  12. 关于Hbase手动实现Major Compact的办法
  13. amazon实例 更改密钥_如何更改Amazon Echo的警报声音
  14. 图谱笔记(概念梳理)
  15. webpack4.0核心概念(七)———— “devtool:source-map“
  16. Excel使用VBA动态设置打印区域
  17. Amino——框架层
  18. [Java] 枚举类型
  19. http://jingyan.baidu.com/article/0eb457e5208cbb03f0a9054c.html
  20. 大法师(简单题总结)

热门文章

  1. sqlserver200864位下载_SQL Server 2008 官方简体中文正式版
  2. 数据结构c语言版编程软件,数据结构严蔚敏4版PDF下载_数据结构C语言版严蔚敏下载 完整版_当载软件站...
  3. 教你如何制作浪漫的表白网站 七夕情人节表白网页在线制作(多种款式)
  4. BIM族库下载——10套知名地产Revit样板文件
  5. 【Multisim】关于Multisim仿真“过零比较器”出现的问题以及解决方法
  6. 对比较器的使用方法的研究
  7. Matlab 2016a 安装教程【转】
  8. ubuntu中vim编辑器的安装与基本使用
  9. 计算机组成原理第一章练习题(答案详解)
  10. Shiro 常用标签