import re
from functools import reduce # 定义一个只计算两个数的乘法或除法的函数:
def multiply_division(exp):
if "*" in exp:
# first=exp.split("*")[0]
# second=exp.split("*")[1]
first,second=exp.split("*")
return float(first)*float(second)
if "/" in exp:
first,second=exp.split("/")
return float(first) / float(second) # 定义一个只计算两个数的加法或减法的函数:
def add_sub(exp):
if "-" in exp:
# first=exp.split("*")[0]
# second=exp.split("*")[1]
first,second=exp.split("-")
return float(first)-float(second)
if "/" in exp:
first,second=exp.split("+")
return float(first) + float(second) # 对于加减法要处理正负号 while循环处理所有的正负号
def exp_fmt(exp):
while re.search('[+-]{2,}',exp): # 循环终止条件是re.search(pattern)为空
exp = exp.replace('--','+')
exp = exp.replace('+-','-')
exp = exp.replace('-+','-')
exp = exp.replace('++','+')
return exp # ret=multiply_division("-1/4")
# print(ret)
# ret=add_sub("1-4")
# print(ret) def multiply_division_replace(exp):
# exp=exp_fmt(exp)
while True:
ret = re.search('\d+(\.\d+)?[*/][+-]?\d+(\.\d+)?', exp)
# ret = re.search('\d+(\.\d+)?[*/]-?\d+(\.\d+)?', exp)
if ret:
res=multiply_division(ret.group(0))
exp=exp.replace(ret.group(0),str(res))
else:
break
return exp # def add_sub_replace(exp):
# while True:
# exp = exp_fmt(exp)
# ret = re.search('\d+(\.\d+)?[+-]\d+(\.\d+)?', exp)
# print(ret.group(0))
# if ret:
# res=add_sub(ret.group(0))
# exp=exp.replace(ret.group(0),str(res))
# else:
# break
# return exp
#
# exp="1—5+2+3" --> -4+2+3 负号没法处理 最终报错
# exp=add_sub_replace(exp)
# print(exp) def remove_addsub(exp):
print(exp)
ret = re.findall('[-+]?\d+(?:\.\d+)?',exp) # (?:\.\d+)
# (?:\.\d+)? 表示一个匹配不用保存的分组,要不然,findall返回的将是括号内的值的列表。
print(ret)
res = reduce(lambda a,b:float(a)+float(b),ret) # 聚合求ret列表内的所有元素的和
return res
# count = 0
# for i in ret:
# count += float(i)
# print(count) exp="1--3*+5/-5+2+3"
# exp="1—5+2+3" --> -4+2+3 负号没法处理
exp=multiply_division_replace(exp)
# exp=add_sub_replace(exp)
print(exp)
老师答案

import re
from functools import reduce def mul_div(exp): # 计算两个数的乘法或者除法
if '*' in exp:
a, b = exp.split('*')
return float(a)*float(b)
if '/' in exp:
a, b = exp.split('/')
return float(a) / float(b) def exp_fmt(exp):
while re.search('[+-]{2,}',exp):
exp = exp.replace('--','+')
exp = exp.replace('+-','-')
exp = exp.replace('-+','-')
exp = exp.replace('++','+')
return exp def remove_addsub(exp):
ret = re.findall('[-+]?\d+(?:\.\d+)?',exp)
res = reduce(lambda a,b:float(a)+float(b),ret)
return res def remove_muldiv(exp): # 计算表达式中的所有的乘除法
while True:
ret = re.search('\d+(\.\d+)?[*/]-?\d+(\.\d+)?',exp)
if ret:
son_exp = ret.group() # 3*4 12*5
res = mul_div(son_exp)
exp = exp.replace(son_exp,str(res))
else:return exp def cal(exp):
res = remove_muldiv(exp) # 计算乘除
res = exp_fmt(res) # 符号整理
ret = remove_addsub(res) # 计算加减
return ret def main(exp):
exp = exp.replace(' ','')
while True:
ret = re.search('\([^()]+\)', exp)
if ret:
res = cal(ret.group())
exp = exp.replace(ret.group(), str(res))
else: return cal(exp) exp = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
ret = main(exp)
print(ret)

python_计算器的更多相关文章

  1. 1.C#WinForm基础制作简单计算器

    利用c#语言编写简单计算器: 核心知识点: MessageBox.Show(Convert.ToString(comboBox1.SelectedIndex));//下拉序号 MessageBox.S ...

  2. 自己动手写计算器v1.1

    这个改动主要是使用工厂模式替代了简单工厂模式,这样做的好处是如果以后我们要扩充其他运算时,就不用总是去修改工厂类, 这是可以采取工厂模式,主要是将原来简单工厂类的逻辑判断分离出来,将它作为一个借口,与 ...

  3. 自己动手写计算器v1.0

    今天突发奇想,想着看了还几个设计模式了,倒不如写点东西来实践它们.发现计算器这种就比较合适,打算随着设计模式的学习,会对计算器不断的做改进. 包括功能的增加和算法的改进.初学者难免犯错,希望大家不吝指 ...

  4. 【IOS开发笔记03-视图相关】简单计算器的实现

    UIView 经过前几天的快速学习,我们初步了解的IOS开发的一些知识,中间因为拉的太急,忽略了很多基础知识点,这些知识点单独拿出来学习太过枯燥,我们在今后的项目中再逐步补齐,今天我们来学习APP视图 ...

  5. [LeetCode] Basic Calculator 基本计算器

    Implement a basic calculator to evaluate a simple expression string. The expression string may conta ...

  6. JS-自制提速小工具:开发页面时需要按比例计算宽高值的快速计算器

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <meta name= ...

  7. 由ArcMap属性字段自增引出字段计算器使用Python的技巧

    1.前言       前些日子有人问我ArcMap中要让某个字段的值实现自增有什么方法?我首先想到像SQL Server中对于数值型字段可以设置自增.所以我打开ArcCatalog查看发现只提供默认值 ...

  8. 前端学PHP之面向对象系列第六篇——简单图形面积计算器实现

    前面的话 本文用面向对象的技术来实现一个简单的图形面积计算器 图形类 //rect.class.php <?php abstract class Shape{ public $name; abs ...

  9. tn文本分析语言(四) 实现自然语言计算器

    tn是desert和tan共同开发的一种用于匹配,转写和抽取文本的语言.解释器使用Python实现,代码不超过1000行. github地址:https://github.com/ferventdes ...

随机推荐

  1. 联赛模拟测试14 A. 虎

    题目描述 这题太虎了,所以没有背景. 给你一棵树,边有黑白两种颜色,你每次可以选择两个点,把这两个点之间的唯一简单路径上的所有边颜色取反,某些边要求最终颜色必须是黑色,还有些边没有要求,问最少操作多少 ...

  2. ConcurrentHashMap原理分析(二)-扩容

    概述 在上一篇文章中介绍了ConcurrentHashMap的存储结构,以及put和get方法,那本篇文章就介绍一下其扩容原理.其实说到扩容,无非就是新建一个数组,然后把旧的数组中的数据拷贝到新的数组 ...

  3. (OK) Android内核(4.9)集成最新版MPTCP---成功

    Android内核(4.9)集成最新版MPTCP---成功

  4. 记录一次源码扩展案列——FastJson自定义反序列化ValueMutator

    背景:曾经遇到一个很麻烦的事情,就是一个json串中有很多占位符,需要替换成特定文案.如果将json转换成对象后,在一个一个属性去转换的话就出出现很多冗余代码,不美观也不是很实用. 而且也不能提前在j ...

  5. MeteoInfoLab脚本示例:读取远程文件

    利用Unidata netCDF Java库对远程文件的读取能力(OpenDAP, ADDE, THREDDS等),可以读取远程文件并绘图.脚本程序: fn = 'http://monsoondata ...

  6. 如何使用懒加载 - umi

    .umirc.js文件 plugins: [       dynamicImport: true,

  7. php休眠微秒

    <?php $child = new \Swoole\Process(function(){ while(true){ echo date("Y-m-d H:i:s").PH ...

  8. 通过SQL自动添加流水号

    通过SQL自动添加流水号 项目中往往有一些单据流水号或者流程流水号是希望通过新增一条记录后自动产生一个编号的,比如新增一条流程就自动根据当前日期自动添加该流程的流程流水号,下面介绍两种不同类型流水号通 ...

  9. Linux文件系统和管理-2文件操作命令(下)

    移动和重命名文件 mv 命令可以实现文件或目录的移动和改名 剪切的效果 同一分区移动数据,速度很快:数据位置没有变化 不同分区移动数据,速度相对慢:数据位置发生了变化 格式 和cp基本一样 mv [O ...

  10. 从一个例子入手Istio

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 本文使用的Istio源码是 release 1.5. 本篇是Istio系列的第一篇,希望 ...