必威体育Betway必威体育官网
当前位置:首页 > IT技术

一元一次方程的解析解(基本字符串处理)

时间:2019-10-18 21:41:05来源:IT技术作者:seo实验室小编阅读:52次「手机版」
 

一元一次方程的解法

工作简历的时候遇到这样一道题,“如何通过基础的解析字符串的方式去求解一元一次方程,而不通过工具包或者内置函数等计算?”,即输入任意一个一元一次函数(如:"((2x+1)*3+1)+(3+2x)=5x+3+(2x+1)"等等  ),当时觉得有趣,于是想好好做一下~

最开始的时候想直接从表达式下手,但是由于有括号对优先级的影响,使得考虑的情况实在是比较复杂,于是便想到分别利用两个栈对表达式求解(data栈用来存储数字{'0','1','2','3','4','5','6','7','8','9','x'},operation栈用来存储操作运算符{'+','-','*','/'},对于利用栈计算算术表达式,这篇博客有详细讲解:https://blog.csdn.net/xyh1re/article/details/81634236。而对于计算x解析解而言,为了方便计算,需要将表达式转换为[a,b]**[x0,x1].T的形式(即a表示常数项,b表示一次项),这里又要分几种情况:

(1)当操作符为{‘+’,‘-’}时,即形如(ax+b),这里经转换得到: np.array([0,a])+np.array([b,0])=np.array([b,a])

(2)当操作符为{‘*’,‘/’}时,即形如(ax+b)*c,这里经转换得到:np.array([b,a])*np.array([c,c]),注意此时的转换方式有变化(不是np.array([c,0]))。

详细的代码如下:

# 将表达式进行标准化,即[a,b]*(x0,x1).T的形式
# 利用两个栈实现表达式的运算
# operation 保存运算符
# data 保存数字
# 遍历表达式,若为数字则直接入栈data,若为符号分几种情况入栈opration:
#     (1)栈为空
#     (2)栈顶为左括号
#     (3)该符号为左括号
#     (4)该符号优先级高于栈顶符号
# 若符号为右括号,则operation输出栈顶符号,从data输出两个数运算再入栈data,
# 直到栈顶为左括号,然后左括号出栈,若符号优先级低于栈顶元素,则重复计算步骤,
# 直到栈为空或栈顶为左括号。
import numpy as np
number={'0','1','2','3','4','5','6','7','8','9','x'}

def data_process1(string):   #如:5x
    if not isinstance(string,str):
        return string
    a=0
    b=0
    index=-1
    for i in range(len(string)):
        if string[i]=="x":
            index=i
    if index==-1:       # 5
        a=float(string)
        b=0.0
    elif index==0:     # x
        a=0.0
        b=1.0
    elif index==1:     # -x,2x
        if string[0]=="-":
            a=0.0
            b=-1.0
        else:
            a=0.0
            b=float(string[0])
    else:               # 5x
        a=0.0
        b=float(string[:index])
    return np.array([a,b])

def data_process2(string):   #如:5x
    if not isinstance(string,str):
        return string
    a=0
    b=0
    index=-1
    for i in range(len(string)):
        if string[i]=="x":
            index=i
    if index==-1:       # 5
        a=float(string)
        b=float(string)
    elif index==0:     # x
        a=0.0
        b=1.0
    elif index==1:     # -x,2x
        if string[0]=="-":
            a=0.0
            b=-1.0
        else:
            a=0.0
            b=float(string[0])
    else:               # 5x
        a=0.0
        b=float(string[:index])
    return np.array([a,b])

def num_operation(num1,num2,op):
    if op=="+":
        return data_process1(num1)+data_process1(num2)
    if op=="-":
        return data_process1(num1)-data_process1(num2)
    if op=="*":
        return data_process2(num1)*data_process2(num2)
    if op=="/":
        return data_process2(num1)/data_process2(num2)

def caculate(data,operation):
    op=operation.pop()
    num2=data.pop()
    num1=data.pop()
    data.APPend(num_operation(num1,num2,op))

def function(s):
    data=[]
    operation=[]
    i=0
    while i<len(s):
        if s[i] in number:       #数字直接入栈data
            start=i
            while i+1 <len(s) and s[i+1] in number:
                i+=1
            data.append(s[start:i+1])
        #栈为空或者栈顶为左括号,入栈operation
        elif not operation or operation[-1]=="(":
            operation.append(s[i])
        #该符号为左括号或优先级高于栈顶元素,入栈operation
        elif s[i]=="(" or (s[i] in {"*","/"} and operation[-1] in {"+","-"}):
            operation.append(s[i])
        #该符号为右括号,则operation出栈,data出栈进行计算
        elif s[i]==")":
            while operation[-1]!="(":
                caculate(data,operation)
            operation.pop()
            #该符号优先级不如栈顶高时,operation出栈,data出栈进行计算,直到栈为空或栈顶为左括号
        else:
            while operation and (operation[-1] in {"*","/"} and s[i] in {"+","-"}):
                if operation[-1]=="(":
                    break
                caculate(data,operation)
            operation.append(s[i])
        i+=1

    while operation:
        caculate(data,operation)
    answer=data.pop()
    if isinstance(answer,str):
        return data_process1(answer)
    return answer

if __name__ == '__main__':
    s=input() # 输入合法的表达式,如  1+((2x+3)*2+1)+2x=5x  请勿带引号输入! 只能一次项!
    # s="1+((2x+3)*2+1)+2x=5x"
    left, right = s.split("=")
    lf=function(left)
    rt=function(right)

    result=lf-rt
    answer=-result[0]/result[1]
    print("the answer is:",answer)

相关阅读

js字符串截取函数slice()、substring()、substr()

原文地址为:js字符串截取函数slice()、substring()、substr()摘要在js中字符截取函数有常用的三个slice()、substring()、substr()

在 Linux shell 字符串中,百分比符号是什么?

当你正在学习如何完全使用 Linux shell 时,你可以能会觉得自己能够对字符串进行操作。 记住,今天q&一个文章的超级用户对读者的一个

将字符串中的rgb颜色转换为16进制

有一个项目需要和原生对接,而原生的颜色无法识别rgb,因此出现了这个转换需求。 细分析,这个需求需要: 1. 提取出rgb颜色 ;  2. 转换r

Java中对于+和append拼接字符串效率的误解

引言   对于初学Java的人来说,在学习String的时候,肯定有无数个人和我们讲过,”尽量不要使用+拼接字符串,效率不好,应该使用append,

js截取字符串第一个汉字

背景: 对接第三方接口需要传个age和ageTyoe字段,其中age字段为integer型,ageType取“岁/月/天”,但是我们系统存的年龄格式为N岁M月,

分享到:

栏目导航

推荐阅读

热门阅读