使用Python实现输入表达式计算,并返回计算结果,主要思路如下:首先逐字符解析计算式,包括计算符号、计算数(注意对负数前负号‘-’的处理)等,然后根据先乘除后加减的计算优先级规则,对解析出来的计算单元执行计算。这里要特别注意对括号的处理,因为括号具有最高的优先级,因此处理算数表达式时,应该先搜索整个表达式的最后一个左括号,再搜索与之匹配的右括号,截取两个括号之间的表达式,先进行运算,计算完括号内表达式之后,用计算结果代替左右括号内所有的内容,并且删除左右括号,计算结果作为一个新的操作数进行处理。如此循环直到所有操作完成。

为了实现上述的计算过程,这里我推荐创建两个堆栈,数字栈和运算符栈,并用一个指针从前往后扫描整个表达式。数字栈保存扫描表达式时提取的操作数以及括号内表达式的中间结果,运算符栈则保存表达式的运算符(+,-,*,/)。

下面介绍具体操作过程:

  • 指针指向数字,直接将数字压入数字栈,指针下移。
  • 指针指向运算符,当栈顶的运算符为左括号,且当前的运算符是右括号,则直接将左括号出栈,指针下移。这种情况不需要计算,直接出栈就行,因为括号内计算已经完成了。
  • 指针指向运算符,但当前栈顶为左括号或者是空栈,又或者当前运算符的优先级高于或者等于栈顶运算符时,应该将当前运算符入栈,指针下移。
  • 除以上情况外的任何情况,从数字栈弹出两个数字作为操作数,从运算符栈弹出一个运算符,参与运输并把获得的运算结果压入数字栈,指针不下移。

重复以上操作过程,直至运算符栈为空,返回数字栈顶元素,也就是表达式的计算结果。但如果出现了以下情况的任何一种情况,就说明原本的表达式不合规范,表达式本身有错误:

  • 运算符栈为空时,数字栈内元素个数大于1
  • 数字栈空了,或只存在一个元素时,运算符栈未空

上代码

步骤1:定义两数字之间的操作计算

def calculate(n1, n2, operator):''':param n1: float:param n2: float:param operator: + - * /:return: float'''result = 0if operator == "+":result = n1 + n2if operator == "-":result = n1 - n2if operator == "*":result = n1 * n2if operator == "/":result = n1 / n2return result# 判断是否是运算符,如果是返回True
def is_operator(e):''':param e: str:return: bool'''opers = ['+', '-', '*', '/', '(', ')']return True if e in opers else False

步骤2:将字符串表达式分割成操作数和运算符,并按顺序保存在表达式列表内

# 能够按照所能匹配的字串将字符串进行切分,返回切分后的字符串列表
re.split(pattern, string[, maxsplit=0, flags=0])
import re# 将算式处理成列表,解决-是负数还是减号
def formula_format(formula):# 去掉算式中的空格formula = re.sub(' ', '', formula)# 以 '横杠数字' 分割, 其中正则表达式:(\-\d+\.?\d*) 括号内:# \- 表示匹配横杠开头; # \d+ 表示匹配数字1次或多次;# \.?表示匹配小数点0次或1次;# \d*表示匹配数字1次或多次。formula_list = [i for i in re.split('(\-\d+\.?\d*)', formula) if i]# 最终的算式列表final_formula = []for item in formula_list:# 第一个是以横杠开头的数字(包括小数)final_formula。# 即第一个是负数,横杠就不是减号if len(final_formula) == 0 and re.search('^\-\d+\.?\d*$', item):final_formula.append(item)continueif len(final_formula) > 0:# 如果final_formal最后一个元素是运算符['+', '-', '*', '/', '(']# 则横杠数字不是负数if re.search('[\+\-\*\/\(]$', final_formula[-1]):final_formula.append(item)continue# 按照运算符分割开item_split = [i for i in re.split('([\+\-\*\/\(\)])', item) if i]final_formula += item_splitreturn final_formula

步骤3:定义运算符压栈的决策函数

def decision(tail_op, now_op):''':param tail_op: 运算符栈的最后一个运算符:param now_op: 从算式列表取出的当前运算符:return: 1 代表弹栈运算,0 代表弹运算符栈最后一个元素, -1 表示入栈'''# 定义4种运算符级别rate1 = ['+', '-']rate2 = ['*', '/']rate3 = ['(']rate4 = [')']if tail_op in rate1:if now_op in rate2 or now_op in rate3:# 说明连续两个运算优先级不一样,需要入栈return -1else:return 1elif tail_op in rate2:if now_op in rate3:return -1else:return 1elif tail_op in rate3:if now_op in rate4:return 0   # ( 遇上 ) 需要弹出 (,丢掉 )else:return -1  # 只要栈顶元素为(,当前元素不是)都应入栈。else:  # 栈顶运算符和当前运算符优先级相同return -1

步骤4:实现表达式计算

def final_calc(formula_list):num_stack = []       # 数字栈op_stack = []        # 运算符栈for e in formula_list:operator = is_operator(e)if not operator:# 压入数字栈# 字符串转换为符点数num_stack.append(float(e))else:# 如果是运算符while True:# 如果运算符栈等于0无条件入栈if len(op_stack) == 0:op_stack.append(e)break# decision 函数做决策tag = decision(op_stack[-1], e)if tag == -1:# 如果是-1压入运算符栈进入下一次循环op_stack.append(e)breakelif tag == 0:# 如果是0弹出运算符栈内最后一个(, 丢掉当前),进入下一次循环op_stack.pop()breakelif tag == 1:# 如果是1弹出运算符栈内最后两个元素,弹出数字栈最后两位元素。op = op_stack.pop()num2 = num_stack.pop()num1 = num_stack.pop()# 执行计算# 计算之后压入数字栈num_stack.append(calculate(num1, num2, op))# 处理大循环结束后 数字栈和运算符栈中可能还有元素 的情况while len(op_stack) != 0:op = op_stack.pop()num2 = num_stack.pop()num1 = num_stack.pop()num_stack.append(calculate(num1, num2, op))return num_stack, op_stack

步骤5:编写主程序,计算表达式结果

if __name__ == '__main__':formula = input('请输入:\n')formula_list = formula_format(formula)result, _ = final_calc(formula_list)print("计算结果:\n", result[0])

运行示例:

(二)Python实现简单计算器相关推荐

  1. python实现简单计算器功能键介绍_Python实现的简单计算器功能详解

    本文实例讲述了Python实现的简单计算器功能.分享给大家供大家参考,具体如下: 使用python编写一款简易的计算器 计算器效果图 首先搭建计算器的面板: 计算器面板结构 建造一个继承于wx.Fra ...

  2. python实现简单计算器_Python实现的简单计算器功能详解

    本文实例讲述了Python实现的简单计算器功能.分享给大家供大家参考,具体如下: 使用python编写一款简易的计算器 计算器效果图 首先搭建计算器的面板: 计算器面板结构 建造一个继承于wx.Fra ...

  3. 如何用Python自制简单计算器?写起来就是那么简单!(代码全)

    大家好,我是你们的python大猿,这是我的一次发文章,请大家多多关照,谢谢大家! 你们平常都是用手机or电脑自带的计算器把,今天,我就带你们用python做一个计算器 首先,我把运行效果放出来: f ...

  4. python计算器简单代码_自学python之简单计算器

    前戏就不多啰嗦了,自爆一下基础,让想学python的朋友有个信心: 我是平面设计出身,现在主要从事的工作是前端狗,所以说我基础也是很弱的,套用一句世界杯期间的广告语: 我不是天生强大,我只是天生要强! ...

  5. [转载] 利用python制作简单计算器

    参考链接: Python程序制作一个简单的计算器 利用python的定义函数,加上if的条件语句进行编程 def add(x, y): """相加"" ...

  6. python实现简单计算器加减乘除功能_Python3实现简单加减乘除运算的计算器

    这是用Python3编写的一个简易的计算器,只有加减乘除,没有括号. 个人思路:将公式以字符串形式传入: 1.去掉其中的空格,生成新的字符串进行操作: 2.提取其中的数字和运算符号分别生产新的列表: ...

  7. python实现简单计算器(加减乘除)

    实现加减乘除计算器 import random count = 0 right = 0 op = ['+','-','*','/']while True:a= random.randint(0,9)b ...

  8. [原创]python之简单计算器(超详解,只有基本功能+-*/,还有括号处理)

     不想看过程的话,直接看文章最后的正式源码 作业需求及分析: 流程图 https://www.processon.com/diagraming/580c5276e4b03c844a5a9716 初期感 ...

  9. python实现简单的四则运算_Python实现简单的四则运算计算器

    一.算法 1.算法的主要思想就是将一个中缀表达式(Infix expression)转换成便于处理的后缀表达式(Postfix expression),然后借助于栈这个简单的数据结构,计算出表达式的结 ...

最新文章

  1. 模拟退火算法通俗讲解
  2. 科大星云诗社动态20210819
  3. SpringBoot 使用 Caffeine 本地缓存
  4. php swoole多进程,PHP基于swoole多进程操作示例
  5. java 注解报错_eclipse编译项目:Java @Override 注解报错的解决方法
  6. 金融统计分析与挖掘实战3.1-3.2
  7. linux驱动编写(其他的驱动代码)
  8. java smtp收信_求一个简单java编写的邮件收发程序,邮件发送程序为smtpsend,邮件接收程序为popreceive。急需,感谢。...
  9. 如何判断python是否安装成功_python怎么判断模块安装完成
  10. IE、火狐导入收藏夹乱码解决方案
  11. wincc怎么c语言编程,WINCC几个常用C语言编程
  12. Android开发面试简历,android开发工程师简历
  13. Visualizing and understanding -- 论文阅读笔记
  14. 磁盘被写保护怎么解除
  15. php免费利用飞信发送验证码,PHP 使用飞信API发送免费短信示例
  16. 参与修谱工作,要具备哪些能力?光会修谱可不行
  17. Unity学习笔记:Tilemap的基础使用【By Chutianbo】
  18. 易语言可以写鸿蒙系统,华为王成录:鸿蒙 OS 系统是不同设备的统一语言
  19. java正则校验密码 长度不少于8位且至少包含大写字母、小写字母、数字和特殊符号中的四种组合 或者 其中任意三种组合
  20. C语言的函数讲解(一)

热门文章

  1. 2022年上海临港新片区科技小巨人(含培育)专项申报工作的通知
  2. C++中的Aggregate
  3. 不同域名网站携带信息跳转并保存到localStorage中
  4. NEU健康上报脚本解析教程
  5. Error:java: Annotation processing is not supported for module cycles.项目启动报错 异常解决
  6. 智能着装:技术将大肆改造时尚业
  7. 最大公约数-最小公倍数
  8. 快乐寒假二,有计划,有坚持,有收获
  9. 常见命令之 head与tail
  10. 路由追踪——traceroute与tracert