Как организовать Поли и создать узел

#python #python-3.x #list #function #linked-list

Вопрос:

В этом классе многочлен принимает список кортежей, подобных таким >>> [(1,2),(3,1),(2,3),(2,2)]

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

Прямо сейчас мой код возвращает это:

 >>> p = Poly([(1,0),(2,2),(1,1),(3,4)])

>>> print(p)

3x^4Traceback (most recent call last):
  Python Shell, prompt 5, line 1
builtins.TypeError: __str__ returned non-string (type NoneType)
 

Это должен быть связанный список, и мне не разрешается организовывать список вручную или преобразовывать его в словарь или любую другую форму. Он должен быть организован с помощью функции вставки и инициализации.

 class Poly:
    class Node:
        def __init__(self, coef, power, _next):
            self._coef = coef   #coefficient from tuple first number
            self._power = power # exponent from tuple second number
            self._next = None
        def __repr__(self):
            pass
    def __init__(self, lst):
        self._head = None
        for i in lst:
            coefficient = i[0]
            exponent = i[1]
            self._head = self.Node(coefficient, expo, self._head)

     
    def __str__(self):
        tmp = self._head
        while tmp != None :
            print(f'{tmp._coef}x^{tmp._power}')
            tmp = tmp._next
    
    def insert(self, tup):
        pass
 

Я попытался сделать цикл while в функции Poly init и разделить оба номера кортежей, но я не уверен, с чего начать в классе Node, и я очень смущен, любая помощь будет признательна и спасибо вам за помощь.

Вот как должен выглядеть результат:

 >>> p0 = Poly([(3,2), (1,0)])

>>> print(p0) 

>>> 1   3x^2

>>> p1 = Poly([(0,3),(4,5),(2,3),(3,4)])

>>> print(p1)

>>> 2x^3   3x^4   4x^5
 

Комментарии:

1. Класс node в порядке, хотя вам не нужен _next в качестве параметра, если вы его не используете. insert Функции просто нужно начать с самого начала и вставить новый узел в нужное место в числовом порядке. Поэтому, если _next она не пуста и _power превышает новую мощность, вставьте новую запись здесь.

2. понятно, но с данными, передаваемыми в виде списка с кортежами, как бы я создал узел в первую очередь, вот что мне интересно? Например, как бы я сказал python, что первое число-это коэффициент, а второе число в кортеже-это степень, а затем перепроверил, больше ли эти степени или нет? Я пробовал цикл while, но я не могу заставить его повторяться и сравнивать без ошибки индекса @TimRoberts

Ответ №1:

Трудно описать этот процесс. Вашему вставщику необходимо просмотреть список в поисках узла, в котором следующий узел имеет более высокую мощность, чем новый узел. Вот где вы вшиваете свою новую запись.

 class Node:
    def __init__(self, coef, power, _next=None):
        self.coef = coef
        self.power = power
        self.next = _next
    def __repr__(self):
        if self.power:
            return f"{self.coef}x^{self.power}"
        return str(self.coef)

class Poly:
    def __init__(self, lst):
        self.head = None
        for i in lst:
            self.insert( i )
     
    def __str__(self):
        if not self.head:
            return "<Poly (none)>"
        nxt = self.head
        parts = []
        while nxt:
            parts.append(str(nxt))
            nxt = nxt.next
        return "<Poly "   ('   '.join(parts))   ">"
    
    def insert(self, tup):
        node = Node(*tup)
        if not self.head:
            self.head = node
            return
        if self.head.power == node.power:
            self.head.coef  = node.coef
            return
        # Loop until the NEXT node's power is larger than the new node.
        nxt = self.head
        while nxt.next and node.power > nxt.next.power:
            if node.power == nxt.power:
                nxt.coef  = node.coef
                return
            nxt = nxt.next
        node.next = nxt.next
        nxt.next = node

p = Poly([(1,0),(2,2),(1,1),(3,4)])
print(p)
p = Poly([(0,3),(4,5),(2,3),(3,4)])
print(p)
 

Выход:

 <Poly 1   1x^1   2x^2   3x^4>
<Poly 2x^3   3x^4   4x^5>
 

Код становится немного проще, если «голова» на самом деле является фиктивным узлом, так что self.head.next у него есть первый узел данных:

 class Poly:
    def __init__(self, lst):
        self.head = Node(-1,-1)
        for i in lst:
            self.insert( i )
     
    def __str__(self):
        nxt = self.head.next
        parts = []
        while nxt:
            parts.append(str(nxt))
            nxt = nxt.next
        return "<Poly "   ('   '.join(parts))   ">"
    

    def insert(self, tup):
        node = Node(*tup)
        # Loop until the NEXT node's power is larger than the new node.
        nxt = self.head
        while nxt.next and node.power > nxt.next.power:
            nxt = nxt.next
        if nxt.next and node.power == nxt.next.power:
            nxt.next.coef  = node.coef
        else:
            node.next = nxt.next
            nxt.next = node
 

Комментарии:

1. ваш код идет в обратном порядке, как бы я упорядочил его так, как он должен быть? например, низшие силы идут первыми, а высшие-последними. Вывод, который вы показываете, не является выводом, полученным из вашего кода.

2. Вывод, который я показал в своем первом коде, в точности совпадает с выводом обоих фрагментов кода. Вывод отображается в порядке возрастания мощностей, что неверно, но это то, о чем вы просили. Если вы не видите этого результата, значит, вы неправильно скопировали мой код.

3. @TimeRoberts Извините, я хотел сказать, что если у вас есть экземпляр, в котором кортежи имеют одинаковую мощность, то оператор if, предназначенный для объединения двух коэффициентов, никогда не происходит, и он просто пропускает его, например… [(1,0),(2,2),(1,1),(3,4),(3,2)] это привело бы к результату <Poly 1 1x^1 3x^2 2x^2 3x^4> вместо 1 1x^1 5x^2 3x^4

4. Ах, так и должно было быть, но там был жучок. Вы пытались это выяснить? Второй фрагмент теперь правильно сочетает равные полномочия.

5. да, я разобрался с этим, не могли бы вы объяснить причину фиктивного узла?

Ответ №2:

Для того, чтобы заказать вещи правильно, сначала мне нужно реализовать функцию вставки, которая смотрит на все сценарии, где мне self._power будет меньше, чем у кортеж положение 1 и случаи, когда оно больше или эквивалент тоже.. после этого я могу перебрать мой список внутри __init__ функции и вызвать пластины(кортеж) с кортежами внутри списка для сортировки.

в моей __str__ функции:

в начале будет достаточно простой пустой строки, и, просматривая ее, я могу продолжать добавлять в пустую строку.