python-数组+递归实现简单代数式运算
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#思路:
#代数式是为字符串
#先将字符串处理为数值与运算符号的数组
#逐项读入数组
#每一次处理不少过两个变量,一个运算符(cos,lg等为单变量运算,使用Var2,+_*?等为双运算符)
#当读入的第二运算符优先于当前运算符,发生递归调用;否则将计算当权运算符与两个变量并返回为一个变量,运算允许无运算符,只返回Var1
#()优先级最高,出现(发生递归调用,表示为Ture,)出现则计算当前运算并返回根层次计算
#lg(5)发生一次运算,lg(5+2)则需要两次运算先做5+2,在做lg7
#即当运算符为单变量运算入sin,cos,lg等,递归调用,表示为Flase,)出现,计算两次,第一次扩号运算,第二次为单变量运算
#全部处理完数组后,可能仍需一次运算
#1、strsplit(strAlgebraic=''): #将输入的预算字串分割为便变量和运算符组成的数组
#2、getprority(stropr=''): #输入运算符,输出优先级数值
#3、calculation(operation ='',var1=0 ,var2=0): #已知变量,运算符,求得运算结构
#lg,sin,cos ,tg,ctg只需要变量2
#没有运算符号返回变量一
#+,-,*,/,%等需要两个变量
#4、Algebraicoperation(isleftbrac=False,var1=None,var2=None,opr=None,AlgebraicList=[],curpos=0 ):
#isleftbrac 左括号调用标识
#var1 ,var2 变量
#opr当前运算符
#代数运算数组AlgebraicList
#数组中当前位置
import math
operationnames = ["(",")",'sin(','cos(','tg(','ctg(','lg(','^','*','%','/','+','-'] #运算父字典
operationprority=[0,0,1,1,1,1,1,1,2,2,2,3,3] #运算符号优先级,与operationnames对应,优先级数值越小优先
#AlgebraicList=[]
def getprority(stropr=''): #输入运算符,输出优先级数值
global operationnames
global operationprority
tmp=operationnames.index(stropr)
if tmp ==None :
print('未发现与%s匹配的运算符!'%stropr)
else:
return operationprority[tmp]
def calculation(operation ='',var1=0 ,var2=0): #已知变量,运算符,求得运算结构
#lg,sin,cos ,tg,ctg只需要变量2
#没有运算符号返回变量一
#+,-,*,/,%等需要两个变量
if operation=='^':
try:
return var1 **var2
except (ValueError, ArithmeticError):
print("程序发生了数字格式异常、算术异常之一")
except:
print("未知异常")
if operation=='+':
return float(var1)+float(var2)
if operation=='%':
try:
return var1%var2
except (ValueError, ArithmeticError):
print("程序发生了数字格式异常、算术异常之一")
except:
print("未知异常")
if operation=='/':
try:
return var1/var2
except (ValueError, ArithmeticError):
print("程序发生了数字格式异常、算术异常之一")
except:
print("未知异常")
if operation=='-':
return var1-var2
if operation=='*':
return var1*var2
if operation=='lg(':
try:
return math.log10(var2)
except (ValueError, ArithmeticError):
print("程序发生了数字格式异常、算术异常之一")
except:
print("未知异常")
if operation =='sin(':
return math.sin(var2)
if operation=='cos(':
return math.cos(var2)
if operation=='tg(':
return math.tan(var2)
if operation=='ctg(':
return 1/math.tan(var2)
if operation==None:
return var1
def Algebraicoperation(isleftbrac=False,var1=None,var2=None,opr=None,AlgebraicList=[],curpos=0 ):
#根据输入的计算序列 数组,递归计算
global operationnames
global operationprority
while curpos <len(AlgebraicList):
if AlgebraicList[curpos] not in operationnames: #当前值不是运算符
if var1 ==None and opr==None:#如果第一变量为空且当前运算符为空时,赋值与第一变量
var1=AlgebraicList[curpos]
else:
var2=AlgebraicList[curpos]#否则赋值第二变量
curpos=curpos+1 #取AlgebraicList下一值
else:
if AlgebraicList[curpos]=='(': #如果为(
if opr==None:#且唯有运算符则递归调用心的Algebraicoperation,返回值赋予第一变量
var1,curpos=Algebraicoperation(True,None,None,None,AlgebraicList,curpos+1)
else:#否则赋值第二变量
var2,curpos=Algebraicoperation(True,None,None,None,AlgebraicList,curpos+1)
elif AlgebraicList[curpos]in ['lg(','cos(','sin(','tg(','ctg(',]: #如果为单变量运算
if opr == None:#且第一编练为空,递归调用新的AlgebraicList,返回与第一变量
var1, curpos = Algebraicoperation(True, None, None, AlgebraicList[curpos], AlgebraicList, curpos +1)
else:#否则返回与第二bl
var2, curpos = Algebraicoperation(True, None, None, AlgebraicList[curpos], AlgebraicList, curpos +1)
elif AlgebraicList[curpos] == ')':#右扩号
if isleftbrac :#为对称左括号
#if opr in ['lg(','log(','cos(','sin(','tg(','ctg(',]:#opr为单变量计算
# return calculation(opr, var1, var2),curpos+1
#else:
return calculation(opr, var1, var2), curpos+1
else:
return calculation(opr, var1, var2),curpos #注意不移动位置,目的是多使用一边)
#例如:sin(a+b),右扩号多使用一边,第一次计算a,b的和,第二次sin和
elif opr==None:#没有当前运算符
opr=AlgebraicList[curpos] #赋值与当前运算符
curpos=curpos+1
else:
if getprority(AlgebraicList[curpos])>=getprority(opr) : #当新获得运算不优先于已有运算符
if opr not in ['lg(','log(','cos(','sin(','tg(','ctg(',]: #且已有运算不是单变量运算时
var1=calculation(opr,var1,var2)#执行已有运算符
opr=AlgebraicList[curpos]
var2=None
curpos=curpos+1
else:
var2,curpos=Algebraicoperation(False,var2,None,AlgebraicList[curpos],AlgebraicList,curpos+1) #否则递归调用新的Algebraicoperation
else:
var2,curpos=Algebraicoperation(False,var2,None,AlgebraicList[curpos],AlgebraicList,curpos+1) #当新获得运算优先于已有运算符,调用新的Algebraicoperation
return calculation(opr,var1,var2) #最后返回计算结果
def strsplit(strAlgebraic=''): #将输入的预算字串分割为便变量和运算符组成的数组
AlgebraicList=[]
tmpvar=''
tmpopr=''
for i in strAlgebraic:
if i in ['+','-','*','/','^','%',')']:
if tmpvar !='':
if '.'in tmpvar:
tmpvar=float(tmpvar)
else:
tmpvar=int(tmpvar)
AlgebraicList.append(tmpvar)
tmpvar=''
AlgebraicList.append(i)
if i.isdigit():
tmpvar=tmpvar+i
if i=='.':
tmpvar=tmpvar+i
if i =='(':
if tmpopr!='':
if tmpopr in ['lg','sin','cos','ctg','tg']:
tmpopr=tmpopr+i
AlgebraicList.append(tmpopr)
tmpopr=''
else:
print('不可识别%s计算符号!'%tmpopr)
return
else:
AlgebraicList.append(i)
if i.isalpha():
tmpopr=tmpopr+i.lower()
if tmpvar !='':
if '.' in tmpvar:
tmpvar = float(tmpvar)
else:
tmpvar = int(tmpvar)
AlgebraicList.append(tmpvar)
return AlgebraicList
print(strsplit('tg(((cos(54-51)+lg(24))))*2'))
print(Algebraicoperation(False,None,None,None,strsplit('tg(((cos(54-51)+lg(24))))*2'),0))
python-数组+递归实现简单代数式运算的更多相关文章
- python数组和矩阵使用总结
python数组和矩阵使用总结 1.数组和矩阵常见用法 Python使用NumPy包完成了对N-维数组的快速便捷操作.使用这个包,需要导入numpy. SciPy包以NumPy包为基础,大大的扩展了n ...
- python 数组学习
2 NumPy-快速处理数据 标准安装的Python中用列表(list)保存一组值,可以用来当作数组使用,不过由于列表的元素可以是任何对象,因此列表中所保存的是对象的指针.这样为了保存一个简单的[1, ...
- python 多线程就这么简单(续)
之前讲了多线程的一篇博客,感觉讲的意犹未尽,其实,多线程非常有意思.因为我们在使用电脑的过程中无时无刻都在多进程和多线程.我们可以接着之前的例子继续讲.请先看我的上一篇博客. python 多线程就这 ...
- python数组的使用
python数组的使用 2010-07-28 17:17 1.Python的数组分三种类型:(1) list 普通的链表,初始化后可以通过特定方法动态增加元素.定义方式:arr = [元素] (2) ...
- Python的变量及简单数据类型
Python的变量及简单类型 1. 变量 在Python编程中,变量是用来存放值或对像的容器.变量的名称可以自定义,但需遵循一定的规范,否则可能会引发一些错误.Python的变量可以分为数字.字符和 ...
- Python与C的简单比较(Python3.0)
Python可以说是目前最火的语言之一了,人工智能的兴起让Python一夜之间变得家喻户晓,Python号称目前最最简单易学的语言,现在有不少高校开始将Python作为大一新生的入门语言.本萌新也刚开 ...
- python的变量和简单的数据类型
决定学习python这门语言了,本人资质愚钝,只会把学到的东西记录下来,供自己查漏补缺,也可以分享给和我一样正在学习python语言的人,若在记录中存在什么错误,希望多多批评指正,谢谢. Python ...
- 说说 Python 的变量以及简单数据类型
1 变量 先来看一个示例: news="我国第一个人工智能规划问世"print(news) 运行结果: 可以看出使用 Python 定义变量很简单,甚至都不需要指定变量的类型. 1 ...
- Python的递归
递归 是指函数/过程/子程序在运行过程序中直接或间接调用自身而产生的重入现象.在计算机编程里,递归指的是一个过程:函数不断引用自身,直到引用的对象已知.使用递归解决问题,思路清晰,代码少.但是在主流高 ...
随机推荐
- Open MPI 4.0 编译安装
电脑上目前使用的mpi环境是2.1.1版本的openmpi,是我之前直接使用系统的包管理工具安装的.但是系统包版本一般都比较老旧,现在openmpi最新版已经出到了4.0,即将出4.1了,所以我打算升 ...
- Overcoming Forgetting in Federated Learning on Non-IID Data
郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! 以下是对本文关键部分的摘抄翻译,详情请参见原文. NeurIPS 2019 Workshop on Federated Learning ...
- 服务器基本配置(ubuntu)
服务器基本配置(ubuntu) 学习目标: 修改初始服务器名字(ubuntu 16.04 ) 修改初始服务器名字(ubuntu 18.04 ) ubuntu换源 更改默认python版本 安装软件出现 ...
- Golang | 简介channel常见用法,完成goroutin通信
今天是golang专题的第14篇文章,大家可以点击上方的专辑回顾之前的内容. 今天我们来看看golang当中另一个很重要的概念--信道.我们之前介绍goroutine的时候曾经提过一个问题,当我们启动 ...
- 【小白学PyTorch】1 搭建一个超简单的网络
文章目录: 目录 1 任务 2 实现思路 3 实现过程 3.1 引入必要库 3.2 创建训练集 3.3 搭建网络 3.4 设置优化器 3.5 训练网络 3.6 测试 1 任务 首先说下我们要搭建的网络 ...
- pybind11: C++ 工程如何提供 Python 接口
C/C++ 工程提供 Python 接口,有利于融合进 Python 的生态.现在 Python 在应用层,有其得天独厚的优势.尤其因为人工智能和大数据的推波助澜, Python 现在以及未来,将长期 ...
- 记录Unity的优化tip(不断更新)
大概记录遇到的可以优化的点.1.Mesh.UploadMeshData:预先把网格送到GPU unity是这样的,它对一个网格,先把它搞到内存,然后在第一次渲染它时把它送到GPU.但送GPU经常是个瓶 ...
- oracle修改管理员密码
运行到C盘根目录 2.输入:SET ORACLE_SID = 你的SID名称 3.输入:sqlplus/nolog 4.输入:connect/as sysdba 5.输入:altre user ris ...
- CentOS 7上更改MySQL数据库存储目录浅析
个人之前总结过两篇文章"MySQL更改数据库数据存储目录"和"Ubuntu上更改MySQL数据库数据存储目录",都是在工作中遇到相关案例后的一个简单总结.当 ...
- Q200510-01: 求部门工资最高的员工
问题: 求部门工资最高的员工 Employee 表包含所有员工信息,每个员工有其对应的 Id, salary 和 department Id. +----+-------+--------+----- ...