python实现计算器

1.题目描述

实现一个计算器的控制台程序,支持加减乘除、乘方、括号、小数点,运算符优先级为括号>乘方>乘除>加减,同级别运算按照从左向右的顺序计算

1.1输入描述

数字包括"0123456789",小数点为".",运算符包括:加("+")、减("-")、乘("*")、除("/")、乘方("^",注:不是**!)、括号("()")

需要从命令行参数读入输入,例如提交文件为main.py,可以用python3 main.py "1+2-3+4"的方式进行调用,Java程序也是类似的,如果你的程序需要通过键盘输入,那么是不符合要求的,例如python使用input()来等待用户输入,这会因为自动评测时不会有用户输入所以不会有任何结果

输入需要支持空格,即 python3 main.py "1 + 2 - 3 + 4" 也需要程序能够正确给出结果,Java程序也是类似的

所有测试用例中参与运算的非零运算数的绝对值范围保证在 109-10(-10) 之内, 应该输出运算结果时非零运算结果绝对值也保证在该范围内

1.2输出描述

数字需要支持小数点,输出结果取10位有效数字,有效数字位数不足时不能补0

对于不在输入描述内的输入,输出INPUT ERROR

对于格式不合法(例如括号不匹配等)的输入,输出 FORMAT ERROR

对于不符合运算符接收的参数范围(例如除0等)的输入,输出VALUE ERROR

对于2、3、4的情况,输出即可,不能抛出异常

同时满足2、3、4中多个条件时,以序号小的为准

1.3样例

输入: 1 + 2 - 3 + 4

输出: 4

输入: 1 + 2 - 3 + 1 / 3

输出: 0.3333333333

输入: 1 + + 2

输出: FORMAT ERROR

输入: 1 / 0

输出: VALUE ERROR

输入: a + 1

输出: INPUT ERROR

2.解决方案

2.1思路

需要格外注意括号,实现运算符的优先级实现

当一个表达式中不含括号的时候是比较好处理的,所以要想办法去掉括号。一个方法是先计算括号内的表达式,然后用计算结果代替这个括号

首先将数字和运算符提取到列表保存,然后对列表中元素逐一处理

去括号:递归的去除最内层的括号

去加减乘除号:依次处理

2.2表达式转变成列表

关于正则表达式请见我的随笔正则表达式

def equation_to_list(equation):

equation_list = re.findall(r"[\d\.]+|\(|\+|\-|\*|\/|\)+", equation)

return equation_list

equation = "(5.4+3.6/3)*1.0"

print(equation_to_list(equation))

# ['(', '5.4', '+', '3.6', '/', '3', ')', '*', '1.0']

2.3完整代码

import re

import sys

def conversionFormula(formula):

format_list = re.findall('[\w\.]+|\(|\+|\-|\*|\/|\^|\)', formula)

switch = 0

switch2 = 0

count = 0

for i in format_list:

if i == '(' or i == ')': # 进行括号符号的判断

switch2 += 1

for i in format_list:

if i == '+' or i == '-' or i == '*' or i == '/' or i == '^': # 进行加减乘除乘方符号的判断

switch = 1

break

if switch != 1:

print('INPUT ERROR')

return 'ERROR'

for i in format_list: # 进行一些错误的判断

if i == '+' or i == '-' or i == '*' or i == '/':

if format_list[count - 1] == '+' or format_list[count - 1] == '-' or \

format_list[count - 1] == '*' or format_list[count - 1] == '/' or \

format_list[count + 1] == '+' or format_list[count + 1] == '-' or \

format_list[count + 1] == '*' or format_list[count + 1] == '/':

print('FORMAT ERROR')

return 'ERROR'

elif i == '/' and format_list[count + 1] == '0':

print('VALUE ERROR')

return 'ERROR'

elif i.isalpha():

print('INPUT ERROR')

return 'ERROR'

count += 1

if switch2 % 2 != 0:

print('FORMAT ERROR')

return 'ERROR'

return format_list

def remove_bracket(formula):

leftBracket = 0

count = 0 # 用遍历列表进行计数

for i in formula:

if i == '(': # 记录最内侧左括号的位置

leftBracket = count

elif i == ')':

smallestFomula = formula[leftBracket + 1:count] # 提取最内层括号里式子

smallestFomulaAnswer = calculator(smallestFomula) # 调用calculator方法进行计算

if smallestFomulaAnswer < 0: # 更新式子,对去括号后的+-,--情况进行分析

if formula[leftBracket - 1] == '-':

formula[leftBracket - 1] = '+'

temp = formula[:leftBracket]

temp.append(str(abs(smallestFomulaAnswer)))

formula = temp + formula[count + 1:]

elif formula[leftBracket - 1] == '+':

formula[leftBracket - 1] = '-'

temp = formula[:leftBracket]

temp.append(str(abs(smallestFomulaAnswer)))

formula = temp + formula[count + 1:]

else:

temp = formula[:leftBracket]

temp.append(str(smallestFomulaAnswer))

formula = temp + formula[count + 1:]

else:

temp = formula[:leftBracket]

temp.append(str(smallestFomulaAnswer))

formula = temp + formula[count + 1:]

return remove_bracket(formula) # 递归,进行新式子的去括号分析

count += 1

return formula # 返回无括号的最终式子

def calculator(formula):

count = 0

for i in formula: # 先处理乘方、乘除

if i == '^':

formula[count - 1] = str(float(formula[count - 1]) ** float(formula[count + 1]))

del (formula[count])

del (formula[count])

return calculator(formula)

elif i == '*':

formula[count - 1] = str(float(formula[count - 1]) * float(formula[count + 1]))

del (formula[count])

del (formula[count])

return calculator(formula)

elif i == '/':

formula[count - 1] = str(float(formula[count - 1]) / float(formula[count + 1]))

del (formula[count])

del (formula[count])

return calculator(formula)

count += 1

count = 0

if formula[0] == '-': # 处理第一个字符是’-’的情况

formula[1] = formula[0] + formula[1]

del (formula[0])

for i in formula: # 处理加减

if i == '+':

formula[count - 1] = str(float(formula[count - 1]) + float(formula[count + 1]))

del (formula[count])

del (formula[count])

return calculator(formula)

elif i == '-':

formula[count - 1] = str(float(formula[count - 1]) - float(formula[count + 1]))

del (formula[count])

del (formula[count])

return calculator(formula)

count += 1

return float(formula[0]) # 返回float型的运算结果

if __name__ == '__main__':

formula = "".join(sys.argv[1:])

formula = conversionFormula(formula)

if formula != 'ERROR': # 错误判断

formula = remove_bracket(formula)

answer = calculator(formula)

if float(answer).is_integer() == True:

answer = int(answer)

else:

answer = format(answer, '.10f') # 空格补0,不足位数不补0

answer = float(str(answer).rstrip('0'))

print(answer)

else:

a = 1

python实现计算器代码 博客园_python实现计算器相关推荐

  1. python的selenium模块博客园_Python学习--Selenium模块学习(2)

    Selenium的基本操作 获取浏览器驱动寻找方式 1. 通过手动指定浏览器驱动路径 2. 通过 `$PATH`环境变量找寻浏览器驱动 控制浏览器访问URL find系列函数定位元素 - `find_ ...

  2. python中json模块博客园_Python中的Json模块详解

    Python中的Json模块详解 Json(JavaScript Object Notation)它是一种轻量级的数据交换格式,具有数据格式简单,读写方便易懂等很多优点.许多主流的编程语言都在用它来进 ...

  3. python中json模块博客园_python的json模块

    python的json模块 什么是序列化和反序列化? 序列化 在分布式环境下,无论是何种数据,都会以二进制序列的形式在网络上传输.序列化是一种将对象以一连串的字节描述的过程,用于解决在对对象流进行读写 ...

  4. python之路 mysql 博客园_Python之路(二十七):Mysql(下)

    本结目录 数据库操作 数据表操作 外键约束 多表查询 索引 事务 python连接Mysql 数据库操作 此操作针对windows环境下 该操作再Mysql服务器启动以及客户端连接之后 对数据库操作之 ...

  5. python tkinter详解 博客园_python tkinter-布局

    包装布局pack() 目前对它的感觉是,当一个窗体的对象都设置完属性后,最后用它来绑定到窗体上.之后就不能再设置属性了 名称 描述 取值范围 expand 当值为"yes"时,si ...

  6. python之路 mysql 博客园_python之路--MySQL数据库初识

    一 . MySQL安装 #下载MySQL地址 https://dev.mysql.com/downloads#要选稳定的,不要选最新的,稳定的就是半年以上没有出现过bug 现在5.6.43为绝大多数使 ...

  7. python博客园_python模拟博客园登录-基础版

    mport time import inspect from functools import wraps user_status = {'username': None,'status': Fals ...

  8. 博客园页面定制html代码,博客园代码定制

    博客园代码定制 版本:2019-08-11 本文基于Simple Memory模板,且已获取CSS和JS权限,此版本并非最终版本. 如有错误请指出,代码开源可以修改完善,仅用于学习交流,转载时请注明出 ...

  9. 博客园页面定制html代码,博客园主题分享

    博客园主题 分享 选择Custom主题 页面定制CSS代码 /*评论框祖传猫猫*/ .comment_textarea{ background:#f5f5f5 url(https://files-cd ...

最新文章

  1. 动态规划---最长公共子序列
  2. Caffe 深度学习框架介绍
  3. ASP.net中页面事件的先后顺序
  4. JAVA数据库连接的另一种实现及简单的数据插入及显示
  5. nyoj655光棍的yy
  6. 一些关于 SAP Spartacus 组件和模块延迟加载的问题和解答
  7. C语言开发笔记(三)自加和自减
  8. 软件手游app介绍推广页html
  9. oracle 10g RAC app VIP ,ONS,GSD,ASM,OCR,VOTE名称及代表的涵义。
  10. C语言之数组探究(一):定义、大小、初始化、访问和三要素
  11. c语言中常用符号,C语言中常用的符号.doc
  12. 推荐系统组队学习——推荐系统概述
  13. 智能优化算法:蛇优化算法-附代码
  14. 数字图像处理-空间域图像增强
  15. 【空气质量数据分析专题四】超标状况分析
  16. wps xml转换表格_WPS文字和Word文档如何转换成表格
  17. Java集合框架中隐藏的设计套路
  18. DIY信号发生器:运放实现三角波、方波发生器(详细参数说明)+multisim仿真
  19. 618 都疯了吗?这些书居然都不到半价!
  20. EXCEL操作视频集1-10

热门文章

  1. 普211标准三维EE零基础转CS申
  2. Delphi中的Type
  3. Java压缩html
  4. sql server 判断是否存在数据库,表,列,视图
  5. 批处理之显示隐藏文件
  6. 什么是索引?为什么要建立索引?并举例说明.(以某一具体的DBMS为例)
  7. 存储器的保护(三)——《x86汇编语言:从实模式到保护模式》读书笔记20
  8. hdu-4825(01字典树)
  9. pat天梯赛L1-051. 打折
  10. 读取CSV内容,根据不同的图片标签放到指定文件夹