保理,替换和打印多项式的根

时间:2014-09-26 06:07:21

标签: python

我们被要求制作一个程序,它接受多项式系数(即[1,2,1]代表x ^ 2 + 2x + 1并使用rational root theorem来查找和打印根分数字符串列表。我们只允许使用导入数学。我的代码的问题是它只有在输入[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

。(我只是从我的编辑器中复制/粘贴代码,因此缩进可能有点偏差)

1 个答案:

答案 0 :(得分:0)

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

此外,更具体地说与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 : \n\t",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执行它(或更改打印调用)。

亚瑟。