python-数组+递归实现简单代数式运算
阅读原文时间:2023年07月12日阅读:1

#!/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 =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))

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章