方程式求有理数解-2

本文探讨如何找到一个整数系数多项式的有理数解。解题思路涉及将多项式分解为(x-p/q)的形式,其中p和q是系数的因数。通过遍历所有可能的p和q组合,检查是否满足多项式为0,来找到有理数解。同时注意负根和重根的处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

给定一个整数系数的多项式,我们要得到所有的有理数解x,使得x代入多项式为0。有理数解就是能用分数表示的解。

解题思路

如果有理数解为p/q,则多项式可分解成若干个(x-p/q)相乘的形式,其中p是多项式常数项系数的因数,q是多项式最高次项系数的因数。这样分解之后x=p/q就是我们需要求的有理数解,所以只需要尝试所有p、q的组合,判断p/q是否满足多项式为0,即可。需要注意的是,(1)要考虑负根(2)不能去掉重根,应该把所有的重根都列出来。

 

代码如下:

#方程式求有理数根

import math
import fractions

def add_poly(L1,L2):#多项式加法
    R=[]
    if len(L1)>len(L2):
        L1,L2=L2,L1
    i=0
    while i<len(L1):
        R.append(L1[i]+L2[i])
        i+=1
    R=R+L2[len(L1):len(L2)]
    return R

def subtract_poly(L1,L2):#多项式减法
    R=[]
    L2=L2[:]#为了不改变原来的L2
    for i in range(len(L2)):
        L2[i]=-L2[i]
    R=add_poly(L1,L2)
    return R

def multiply_poly(L1,L2):#多项式乘法
    if len(L1)>len(L2):
        L1,L2=L2,L1
    zero=[];R=[]
    for i in L1:
        T=zero[:]
        for j in L2:
            T.append(i*j)
        R=add_poly(R,T)
        zero=zero+[0]
    return R

def divide_poly(L1,L2):#多项式除法
    if len(L1)<len(L2):return [0]
    d=len(L1)-len(L2)
    T=L1[:];R=[]
    for i in range(d+1):
        n=T[len(T)-1]/L2[len(L2)-1]
        R=[n]+R
        T1=[0]*(d-i)+[n]
        T2=multiply_poly(T1,L2)
        T=subtract_poly(T,T2)
        T=T[:len(T)-1]
    return R

def check(L,s):#检查根代入方程式是否为0
    sum1=0
    for t in range(len(L)):
        if t==0:sum1=sum1+L[t]
        else:sum1=sum1+L[t]*s**t
    if abs(sum1)<1e-15:return True  #检查sum1是否和0相等,一个小数的绝对值小于le-15就近似等于0.
    else:return False
    
    #if round(sum1, 20) < 1e-15:
    #   return True
    #else:
    #   return False

def rational(L):
    R=[]#存放最高次项系数的因数
    T=[]#存放常数项系数的因数
    S=[]#存放结果
    
    #求出次数最高次项系数的因数存放在R中
    k1=1
    while k1<=math.sqrt(abs(L[len(L)-1])):
        q=L[len(L)-1]/k1
        if int(q)==q:
            if q==k1 :
                R.append(int(q))
            else:
                R.append(k1)
                R.append(int(q))
        k1=k1+1
    #print(R)
        
    #求出常数项的所有因数存放在T中    
    k2=1
    while k2<=math.sqrt(abs(L[0])):
        p=L[0]/k2
        if int(p)==p:
            if p==k2 :
                T.append(int(p))
            else:
                T.append(k2)
                T.append(int(p))
        k2=k2+1
    #print(T)
   
    for i in T:
        for j in R:
            s1 = fractions.Fraction(i, j)#s1=i/j
            while check(L,s1):#用while循环主要是为了不去除重根
                S.append(s1)
                L=divide_poly(L,[-s1,1])#得到一个根之后就去除去一个因式ax-1,更新被除数
                #print(1,L,S)
                
            s2 = fractions.Fraction(-i, j)#s2是为了验证负根s2=-i/j
            while check(L,s2):
                S.append(s2)
                L=divide_poly(L,[-s2,1])
                #print(2,L,S)
        #print(S)
    return S

def to_String(S):#把多项式列表转化成表达式
    str1=""
    for x in S:
        if x==0:str1="x"
        elif x>0:
            str1="(x-"+str(x)
        else :str1="(x+"+str(abs(x))
        str1=str1+")"
        print(str1,end="")
    print("\n")
    
while True:
    s=input("请输入一个方程式的系数(低次项系数在前,以空格分隔)")
    L1=s.split(" ")
    L=[int(e) for e in L1]
    print("L:",L)
    S=rational(L)
    if len(S)==0:
        print("No solution!\n")
    else:
        print("方程分解成有理数根的形式是:",end="")
        to_String(S)
        
            

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值