多项式的因式分解、置换和打印根



我们被要求制作一个程序,该程序接受表示x^2+2x+1的多项式系数(即[1,2,1]),并使用有理根定理在分数字符串列表中查找和打印根。我们只被允许使用导入数学。我的代码的问题是,只有当我输入[1,2、1]时,它才有效当我输入其他多项式时,它会打印一个空白列表。

import math
roots = []
pr = []
pf = []
qf = []
count = 1 
t = 0
co = raw_input('Input Coefficients: ')
co = co.split(' ')
p = co[0]
q = co[-1]

def gcd(a,b): #function for computing gcf between two numbers. will be used to simplify fractions into lowest terms
    r = a%b     
    if r == 0:
        return b
    else:
        return gcd(b,r) 

def rmvvalues(coefficients, val): #remove the zeroes from the list because zero is not factorable
    for i in range(coefficients.count(val)):
        coefficients.remove(val)
while int(p) == 0: #if the constant was 0, it means 0 is automatically a root
    roots.append(0)
    rmvvalues(co, str('0'))
    p = co[0]
    q = co[-1]
while count <= math.fabs(int(p)): #factors of the constant
    if int(p) % count == 0:
        pf.append(count)
        pf.append(count*(-1))
        count = count + 1
    else:
        count = count + 1
count = 1
while count <= math.fabs(int(q)): #factors of the last term
    if int(q) % count == 0:
        qf.append(count)
        qf.append(count*(-1))
        count = count + 1
    else:
        count = count + 1
count = 1
for i in range(len(pf)): #every element in the first list of factors is to be divided by every element of the other list of factors
    for j in range(len(qf)): 
        result = 0
        for c in range(len(co)): #and each pf/qf is to be checked if it would make the polynomial zero
            result = int(result) * (int(pf[i])/int(qf[j])) + int(co[c])
        if result == 0: #if it makes it zero, it appends the answer in fraction string to the list of roots
            if (int(pf[i]) / int(qf[j])) == 1: #add 1 to the list of roots if p/q == 1 and would make the equation zero
                roots.append(1)
            elif int(pf[i])/int(qf[j]) == -1: #add -1 to the list of roots if p/q == -1 and would make the equation zero
                roots.append(-1)
            else: #if they would be fractions
                a = int(pf[i]) / int(gcd(int(pf[i]),int(qf[j])))
                b = int(qf[j]) / int(gcd(int(pf[i]),int(qf[j])))
                roots.append(str(a) + '/' +str(b))
            roots = sorted(set(roots))
print roots

p.s.(我只是从编辑器中复制/粘贴代码,所以缩进可能有点偏离)

我有一个实现要建议,但不是您的调试。事实上,你正在写一个我不理解的大的一块代码。由于我想帮助你,我给你一个实现的例子,我希望你会觉得有用和可读。在编码时,我的大建议是将代码拆分成一个易于理解的小函数,并命名为有意义的名称,然后添加一个调用所有子函数的算法函数。这使得算法看起来像伪代码并且是模式可理解的。

此外,更具体地说,与python相关,您的代码应该遵循一些规则。运行时代码应该放在if __name__ == "__main__":块之后。

希望它能帮助你(看看findSolution方法):

class Polynom():
    """ A class representing a polynom that provides methods to find roots of the polynom. """
    #-----------------------------------------------------------------------------------------
    def __init__(self, coefficients):
        """
        Constructor of the class.
        Takes a coeficient list [n, n-1, ..., n1, n0] that are the coefficients of a polynom.
        Example : 
            Polynom([1,2,3]) stand for : x² + 2x + 3
        """
        self.coefficients = coefficients
    #-----------------------------------------------------------------------------------------
    def _dividers(self, coefficient):
        """Returns the list of the divider of a number by filtering the values in [1, 2, ... , |coefficient| ] that divide coefficient. """
        def filter_dividers(coefficient, candidate_values):
            # lambda function explanations : http://www.diveintopython.net/power_of_introspection/lambda_functions.html
            return filter(lambda number : coefficient%number == 0, candidate_values)
        return list(filter_dividers(coefficient, range(1, abs(coefficient)+1)))
    #-----------------------------------------------------------------------------------------
    def _gcd(self, x, y):
        """ Returns the greatest common diviser of the integers x and y """
        if y == 0:
            return abs(x)
        else:
            r = x%y
            return self._gcd(y, r)
    #-----------------------------------------------------------------------------------------      
    def _positiveAndNegativeCombinations(self, p_values, q_values):
        """
        Returns the list of positives and negatives combination of (p,q) pairs.
        Example : 
            [1,2]
                    -> [(1,4), (-1,4), (2,4), (-2,4), (1,5), (-1,5), (2,5), (-2,5)]
            [4,5]
        """
        def combinations(p, q_values):
            if len(q_values) == 1:
                return [(p, q_values[0])]
            else:
                return [(p, q_values[0])] + combinations(p, q_values[1:])
        result = []
        for p in p_values:
            p_combinations = combinations(p, q_values)
            for combination in p_combinations:
                result += [combination, (-1*combination[0], combination[1])]
        return result
    #-----------------------------------------------------------------------------------------          
    def __repr__(self):
        """ Representation of the object in a string for printing purpose."""
        def from_number_to_string_exposant(number):
            """
            Returns a string that is the number given as exposant.
            Example : 1 ->  "¹"
            """
            utf8_exposant = {"0":"⁰", "1":"¹", "2":"²", "3": "³", "4":"⁴", "5":"⁵", "6":"⁶", "7":"⁷", "8":"⁸", "9":"⁹"}
            string = str(number)
            result = ""
            for digit in string:
                result += utf8_exposant[digit]
            return result
        result = ""
        degree = 0
        coefficients = self.coefficients
        while coefficients != [] :
            coef, coefficients = coefficients[-1], coefficients[0:-1]
            result = "+ " +str(coef)+"x"+ from_number_to_string_exposant(degree) + result
            degree+=1
        return "<Polynom :" + result[1:] + " = 0 >"     
    #-----------------------------------------------------------------------------------------
    def valueFor(self, value):
        """ Returns ture or false depending on the fact that the given value is or not a polunom's solution. """
        total_value = 0
        degree = 0
        coefficients = self.coefficients
        while coefficients != [] :
            coef, coefficients = coefficients[-1], coefficients[0:-1]
            total_value += coef*(value**degree)
            degree += 1
        return total_value
    #-----------------------------------------------------------------------------------------
    def isSolution(self, value):
        """ Returns true or false depending if the given value is a polynom solution or not """
        return (self.valueFor(value) == 0)
    #-----------------------------------------------------------------------------------------
    def findSolution(self):
        """
        Return a pair (p,q) that verify that p/q is a solution of this polynom. If no valid pair is find, return None.
        Call to this function come with log printing.
        """
        print("Search solution for ", self)
        a0 = self.coefficients[-1]
        aN = self.coefficients[0]
        if a0 == 0 or aN == 0:
            return None #algorithm is not applicable in this case.
        else:
            p_values = self._dividers(a0)
            q_values = self._dividers(aN)
            print("finded dividers of p :", p_values)
            print("finded dividers of q :", q_values)
            candidate_solutions = self._positiveAndNegativeCombinations(p_values,q_values)
            print("(p,q) pairs to evaluate are : nt",candidate_solutions)
            for candidate in candidate_solutions :
                candidate_value = 1.0 * candidate[0] / candidate[1]
                print("pair : ",candidate, " | value : ", candidate_value)
                if self.isSolution(candidate_value):
                    print()
                    return candidate
                else:
                    print("The pair ", candidate, "is invalid, replacing x by it leads to say that 0=", self.valueFor(candidate_value))
            return None
    #-----------------------------------------------------------------------------------------

if __name__ == "__main__":
    poly = Polynom([2,1,-6])
    print(poly.findSolution())

使用python3执行它(或者更改打印调用)。

亚瑟。

https://code.activestate.com/recipes/577974-polynomial-factoring-using-rational-root-theorem/这是一个工作链接。

from math import ceil
listOfFactors = lambda n: {i for i in range(1,ceil(abs(n)/2)+1) if n%i == 0}
def removeDuplicates(mylist):
    if mylist:
        mylist.sort()
        last = mylist[-1]
        for i in range(len(mylist)-2, -1, -1):
            if last == mylist[i]:
                del mylist[i]
            else:
                last = mylist[i]
    return mylist
def polyRoots(polyListCoeff):
    allFactors = set()
    allFactorsListOld = list(allFactors.union(listOfFactors(polyListCoeff[0]),{polyListCoeff[0]},listOfFactors(polyListCoeff[-1]),{polyListCoeff[-1]}))
    allFactorsListOld.extend([-1*i for i in allFactorsListOld])
    allFactorsList = list()
    for k in allFactorsListOld:
        for j in allFactorsListOld:
            allFactorsList.append(k/j)
    allFactorsList = removeDuplicates(allFactorsList)
    polyListCoeff.reverse()
    roots = [i for i in allFactorsList if sum([pow(i,j)*polyListCoeff[j] for j in range(0,len(polyListCoeff))]) == 0]
    factorList = list()
    for i in roots:
        if i<0:
            factorList.append("(x+{})".format(-i))
        else:
            factorList.append("(x-{})".format(i))
    return "".join(factorList)

if __name__ == "__main__":
    polyRoots([1,0,-4])
#   '(x+2.0)(x-2.0)'

最新更新