计算器源码(数学式python)
'''
******************** 请计算表达式: 1 - 2 * ( (60-30 +(-40.0/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) ) ********************
(-40.0/5) 计算后为 (-8.0) ;则式子化简为: 1-2*((60-30+(-8.0)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))
(9-2*5/3+7/3*99/4*2998+10*568/14) 计算后为 173545.88095238098 ;则式子化简为: 1-2*((60-30+(-8.0)*173545.88095238098)-(-4*3)/(16-3*2))
(60-30+(-8.0)*173545.88095238098) 计算后为 (-1388337.0476190478) ;则式子化简为: 1-2*((-1388337.0476190478)-(-4*3)/(16-3*2))
(-4*3) 计算后为 (-12.0) ;则式子化简为: 1-2*((-1388337.0476190478)-(-12.0)/(16-3*2))
(16-3*2) 计算后为 10.0 ;则式子化简为: 1-2*((-1388337.0476190478)-(-12.0)/10.0)
((-1388337.0476190478)-(-12.0)/10.0) 计算后为 (-1388335.8476190479) ;则式子化简为: 1-2*(-1388335.8476190479)
最后结果为: 2776672.6952380957
'''
基于递归和正则表达式实现的,源码如下:
# Author: Alan
import re
#实现输入数学式子(python里),计算其结果,类似计算器。思路如下:
#1.去括号:先计算最里层括号内的表达式(正则抓出)并计算出值,然后完成替换,最后循环此步骤(递归),直到没有括号或其内无表达式
#2.表达式(没有括号的干扰)计算:按运算符优先级(正则抓出)依次计算出值(递归),然后完成替换,最后会返回一个值(负数则用小括号括起)
#3.支持:python **,%,//等运算,小括号,中括号,及大括号(其实原理是一样的,正则都类似)
#4.坑:替换时如果用re.sub,由于式子包含一些特殊字符需要转义才能替换,然而我用的是replace
#5.输入:如果不是位于表达式的开头的负数请用小括号括起,避免符号混乱
def count_ex(list,strx):
#计算一次结果 负数用()括起来
list_left=re.sub('[\(\)]*','',list[0])
list_right=re.sub('[\(\)]*','',list[2])
list_sym=list[1]
list_str=''.join(list)
if list_sym=='**':
num=float(list_left)**float(list_right)
sym_str=str(num) if num>0 else '(%s)'%num #计算结果
return strx.replace(list_str,sym_str,1)
elif list_sym=='//':
num = float(list_left) // float(list_right)
sym_str = str(num) if num > 0 else '(%s)' % num # 计算结果
return strx.replace(list_str,sym_str,1)
elif list_sym=='%':
num = float(list_left) % float(list_right)
sym_str = str(num) if num > 0 else '(%s)' % num # 计算结果
return strx.replace(list_str,sym_str,1)
elif list_sym=='/':
num = float(list_left) / float(list_right)
sym_str = str(num) if num > 0 else '(%s)' % num # 计算结果
return strx.replace(list_str,sym_str,1)
elif list_sym=='*':
num = float(list_left) * float(list_right)
sym_str = str(num) if num > 0 else '(%s)' % num # 计算结果
return strx.replace(list_str,sym_str,1)
elif list_sym=='+':
num = float(list_left) + float(list_right)
sym_str = str(num) if num > 0 else '(%s)' % num # 计算结果
return strx.replace(list_str,sym_str,1)
elif list_sym=='-':
num = float(list_left) - float(list_right)
sym_str = str(num) if num > 0 else '(%s)' % num # 计算结果
return strx.replace(list_str,sym_str,1) def regex_split(str,pattern):
#处理算术运算符
list = re.findall(pattern, str)
if not list:
return str
else:
str = count_ex(list[0], str)
return regex_split(str,pattern) def bracket(strx):
#处理括号中的内容,顺序小括号,中括号,大括号。结束条件没有中括号及大括号和小括号内无表达式(递归)
regex_bracket=[
'\((?:[\-]?\d+\.?\d*|\([\-]?\d+\.?\d*\))(?:(?:\*\*|\/\/|\%|\*|\/|\+|\-)(?:\d+\.?\d*|\([\-]?\d+\.?\d*\))*)+\)',
'\[(?:[\-]?\d+\.?\d*|\([\-]?\d+\.?\d*\))(?:(?:\*\*|\/\/|\%|\*|\/|\+|\-)(?:\d+\.?\d*|\([\-]?\d+\.?\d*\))*)+\]',
'\{(?:[\-]?\d+\.?\d*|\([\-]?\d+\.?\d*\))(?:(?:\*\*|\/\/|\%|\*|\/|\+|\-)(?:\d+\.?\d*|\([\-]?\d+\.?\d*\))*)+\}'
]
for i in regex_bracket:
list=re.findall(i, strx)
if not list:continue
else:
strx1=deal_expression(list[0][1:-1])#去掉最外层括号并处理此表达式
strx=strx.replace(list[0], strx1, 1)#完成替换
print(list[0],'计算后为',strx1,';则式子化简为:',strx)
res_end=re.findall(
'(\{|\[|\((?:[\-]?\d+\.?\d*|\([\-]?\d+\.?\d*\))(?:(?:\*\*|\/\/|\%|\*|\/|\+|\-)(?:\d+\.?\d*|\([\-]?\d+\.?\d*\))*)+\))',
strx)
if not res_end:return strx#结束条件
return bracket(strx) def deal_expression(strx):
#处理表达式,运算符优先级,先**,在//,%,/,*,最后+,-
rank_sym_pattern=[
'(\([\-]?\d+\.?\d*\)|^\-\d+\.?\d*|\d+\.?\d*)(\*\*)(\([\-]?\d+\.?\d*\)|\d+\.?\d*)',
'(\([\-]?\d+\.?\d*\)|^\-\d+\.?\d*|\d+\.?\d*)(\%|\/\/|\*|\/)(\([\-]?\d+\.?\d*\)|\d+\.?\d*)',
'(^\-\d+\.?\d*|\d+\.?\d*|\([\-]?\d+\.?\d*\))(\+|\-)(\([\-]?\d+\.?\d*\)|\d+\.?\d*)'
]
for i in rank_sym_pattern:
strx=regex_split(strx, i)
return strx def run():
while True:
ex = input('ex>>>:').strip()
if not ex: continue
if ex == 'q': break
ex=re.sub('\s','',ex)
print('最后结果为:',deal_expression(bracket(ex)).strip('()')) if __name__ == '__main__':
run() # expression='22//2+1-2*((60+2*(-3-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-((-4)*3)/(16-3*2))'
# print(deal_expression(bracket(expression)))
转载请注明出处!!!!!!!!!!!!!!!!!!
计算器源码(数学式python)的更多相关文章
- socket_server源码剖析、python作用域、IO多路复用
本节内容: 课前准备知识: 函数嵌套函数的使用方法: 我们在使用函数嵌套函数的时候,是学习装饰器的时候,出现过,由一个函数返回值是一个函数体情况. 我们在使用函数嵌套函数的时候,最好也这么写. def ...
- 学习 vue 源码 -- 响应式原理
概述 由于刚开始学习 vue 源码,而且水平有限,有理解或表述的不对的地方,还请不吝指教. vue 主要通过 Watcher.Dep 和 Observer 三个类来实现响应式视图.另外还有一个 sch ...
- 源码包安装(Python mysql redis)
一 源码包安装 (1)python3.6源码包安装 ./configure ------> 定制功能 make make install mysql 源码包 cmake make make i ...
- Android-看操作系统短信应用源码-隐式意图激活短信界面
选择模拟器Unknown Google Nexus,在选择system_process(系统进程) 操作模拟器的,操作系统短信应用,让操作系统短信打印日志,来查看: 然后就找到来,操作系统短信应用打印 ...
- pytorch源码解析:Python层 pytorchmodule源码
尝试使用了pytorch,相比其他深度学习框架,pytorch显得简洁易懂.花时间读了部分源码,主要结合简单例子带着问题阅读,不涉及源码中C拓展库的实现. 一个简单例子 实现单层softmax二分类, ...
- [Python源码剖析]获取Python小整数集合范围
#!/usr/bin/env python #-*- coding=utf-8 -*- small_ints = dict() for i in range(-10000,10000): small_ ...
- 从 CPython 源码角度看 Python 垃圾回收机制
环状双向链表 refchain 在 Python 程序中创建的任何对象都会被放到 refchain 链表中,当创建一个 Python 对象时,内部实际上创建了一些基本的数据: 上一个对象 下一个对象 ...
- 官网服务质量检测脚本(源码来自《Python自动化运维实战》第二版刘天斯)
脚本Python版本2.7 #!/usr/bin/python #-*- coding:utf-8 -*- import os,sys import time import sys import py ...
- 源码升级安装python
1.下载 python: https://www.python.org/downloads/release/python-2712/ 2.编译安装 sudo mkdir /usr/local/pyth ...
随机推荐
- Material Design之CoordinatorLayout+AppBarLayout实现上滑隐藏ToolBar
ok,今天继续更新Material Design系列!!! 废话不说,先看看效果图吧: 好了,现在来讲讲上图是怎么实现的吧!讲之前先讲讲几个控件: CoordinatorLayout 该控件也是De ...
- 操作系统 - Linux进程实现的内部结构
在进程描述符中进入几个字段来表示进程之间的父子关系和兄弟关系. 图3-4显示了一组进程间的亲属关系. 表3-4:建立非亲属关系的进程描述符字段 在某些情况下,内核必须能从进程的PID到处对应的进程描述 ...
- 第十一章 图像之2D(1)SpriteBatch
Android游戏开发群:290051794 Libgdx游戏开发框架交流群:261954621 作者:宋志辉 出处:http://blog.csdn.net/song19891121 本文版权归作 ...
- Xcode自定义字体不能应用的原因
想给UILabel换一个自定义的字体,从字体册选择兰亭黑: 然后选择 在Finder中显示,找到字体文件为Lantinghei.ttc: 将其拷贝到项目中,在info.plist里添加字体支持key, ...
- Linux磁盘 - fdisk,partprobe, mkfs, mke2fs, fsck, badblocks, mount, mknod
磁盘分区: fdisk [root@www ~]# fdisk [-l] 装置名称 选项与参数: -l :输出后面接的装置所有的 partition 内容.若仅有 fdisk -l 时, 则系统将会把 ...
- STM32之使用库函数驱动LED灯
一.熟悉GPIO结构体 以下这个结构体是我从官方手册中获取的: typedef struct { u16 GPIO_Pin; GPIOSpeed_TypeDef GPIO_Speed; GPIOMod ...
- LeetCode之旅(19)-Power of Two
题目 Given an integer, write a function to determine if it is a power of two. Credits: Special thanks ...
- 2018 ACM-ICPC World Finals B.Comma Sprinkler
WF里面最简答一题,就是一个dfs就可以了,已经访问过的点可以不再访问 #include <algorithm> #include <cmath> #include <c ...
- webpack.config.js配置文件
1.基本配置 webpack在执行时,除在命令行传入参数,还可以通过指定的配置文件来执行.默认会搜索当前目录下webpack.config.js.这个文件是一个node.js模块,返回一个json格式 ...
- Python list 两个不等长列表交叉合并
遇到一个需求,需要对两个长度不一定相等的列表进行交叉合并.像拉拉链一样(两边的拉链不一定相等). 如: a = [1, 3, 5] b = [2, 4, 6, 8] 需将a, b 合并为 c c = ...