Как посчитать сумму двух многочленов?

Например, 3x^4 - 17x^2 - 3x + 5. Каждый член полинома может быть представлен как пара целых чисел (коэффициент, показатель степени). Сам полином представляет собой список таких пар, как
[(3,4), (-17,2), (-3,1), (5,0)] для полинома, как показано.

Нулевой многочлен 0 представлен пустым списком [], так как в нем нет членов с ненулевыми коэффициентами.

Я хочу написать две функции для сложения и умножения двух входных полиномов с одинаковым представлением кортежа (коэффициент, показатель степени):

  1. addpoly(p1, p2)
  2. multpoly(p1, p2)

Тестовые случаи:

  • addpoly([(4,3),(3,0)], [(-4,3),(2,1)])
    должен дать [(2, 1),(3, 0)]

  • addpoly([(2,1)],[(-2,1)])
    должен дать []

  • multpoly([(1,1),(-1,0)], [(1,2),(1,1),(1,0)])
    должен дать [(1, 3),(-1, 0)]

Вот то, с чего я начал, но был полностью поражен!

def addpoly(p1, p2):
    (coeff1, exp1) = p1
    (coeff2, exp2) = p2
    if exp1 == exp2:
        coeff3 = coeff1 + coeff2

person Agarwal Prega    schedule 20.08.2016    source источник
comment
Вы должны сначала найти или разработать алгоритм (математический или на естественном языке) для арифметики на разреженных представлениях многочленов с одним неопределенным. До тех пор это не вопрос программирования.   -  person Terry Jan Reedy    schedule 20.08.2016
comment
вам нужно приложить немного больше усилий, если вам нужна помощь. по крайней мере, ваша функция что-то возвращает.   -  person user1269942    schedule 20.08.2016
comment
Возможно, было бы лучше сделать каждый многочлен словарем, состоящим из сопоставления ключа экспоненты с соответствующим коэффициентом. Таким образом, образец в вашем вопросе будет выглядеть так: {4: 3, 2: 17, 1: 3, 0: 5}. С такой структурой данных стало бы относительно легко получить доступ к терминам (или проверить их существование) в каждом многочлене, переданном функциям. Кроме того, это просто вопрос реализации того, что вы сделали бы, если бы делали это вручную с помощью карандаша и бумаги.   -  person martineau    schedule 20.08.2016
comment
collections.Counter делает addpoly тривиальной задачей   -  person VPfB    schedule 20.08.2016
comment
Если вы не ожидаете, что ваши полиномы будут очень разреженными и очень высокой степени, вам почти наверняка лучше представить их в виде списка коэффициентов, где первая запись является коэффициентом x ^ 0, вторая - коэффициентом x ^ 1 и т. д. , Таким образом, вы можете просто добавить запись. Результат имеет длину, равную длине самого длинного многочлена. И его степень легко выводится из самого объекта.   -  person Jeremy West    schedule 20.08.2016


Ответы (3)


Как предложено в комментарии, гораздо проще представлять многочлены как мультимножества показателей степени.

В Python ближе всего к мультимножеству находится счетчик. структура данных. Использование Counter (или даже простого словаря), который сопоставляет экспоненты с коэффициентами, автоматически объединяет записи с одинаковыми экспонентами, как и следовало ожидать при написании упрощенного многочлена.

Вы можете выполнять операции, используя Counter, а затем преобразовать обратно в представление списка пар, когда закончите, используя такую ​​​​функцию:

def counter_to_poly(c):
    p = [(coeff, exp) for exp, coeff in c.items() if coeff != 0]
    # sort by exponents in descending order
    p.sort(key = lambda pair: pair[1], reverse = True)
    return p

Чтобы сложить многочлены, вы группируете одинаковые показатели степени и суммируете их коэффициенты.

def addpoly(p, q):
    r = collections.Counter()

    for coeff, exp in (p + q):
        r[exp] += coeff

    return counter_to_poly(r)

(На самом деле, если бы вы все время придерживались представления Counter, вы могли бы просто return p + q).

Чтобы умножить многочлены, вы умножаете каждый член одного полинома попарно на каждый член другого. И, кроме того, чтобы умножить термины, вы добавляете показатели степени и умножаете коэффициенты.

def mulpoly(p, q):
    r = collections.Counter()

    for (c1, e1), (c2, e2) in itertools.product(p, q):
        r[e1 + e2] += c1 * c2

    return counter_to_poly(r)
person lazy dog    schedule 20.08.2016

Этот код Python сработал для меня, надеюсь, сработает и для вас...

Функция добавления

def addpoly(p1,p2):
i=0
su=0
j=0
c=[]
if len(p1)==0:
    #if p1 empty
    return p2
if len(p2)==0:
    #if p2 is empty
    return p1
while i<len(p1) and j<len(p2):
    if int(p1[i][1])==int(p2[j][1]):
        su=p1[i][0]+p2[j][0]
        if su !=0:
            c.append((su,p1[i][1]))
        i=i+1
        j=j+1
    elif p1[i][1]>p2[j][1]:
        c.append((p1[i]))
        i=i+1
    elif p1[i][1]<p2[j][1]:
        c.append((p2[j]))
        j=j+1
if p1[i:]!=[]:
    for k in p1[i:]:
        c.append(k)
if p2[j:]!=[]:
    for k in p2[j:]:
        c.append(k)
return c  

Функция умножения

def multipoly(p1,p2):
p=[]
s=0
for i in p1:
    c=[]
    for j in p2:
        s=i[0]*j[0]
        e=i[1]+j[1]
        c.append((s,e))
    p=addpoly(c,p)
return p 
person Partha debnath    schedule 05.09.2018

Я придумал решение, но я не уверен, что оно оптимизировано!

    def addpoly(p1,p2):
        for i in range(len(p1)):
            for item in p2:
                if p1[i][1] == item[1]:
                    p1[i] = ((p1[i][0] + item[0]),p1[i][1])
                    p2.remove(item)
        p3 = p1 + p2
        for item in (p3):
            if item[0] == 0:
                p3.remove(item)
        return sorted(p3)

и второй:-

    def multpoly(p1,p2):
        for i in range(len(p1)):
            for item in p2:
                p1[i] = ((p1[i][0] * item[0]), (p1[i][1] + item[1]))
                p2.remove(item)
        return p1
person Agarwal Prega    schedule 23.08.2016