Реализация функции сортировки слиянием в классе Python, ошибки - PullRequest
0 голосов
/ 08 июня 2018

Итак, у меня есть определенная функция, которая отлично работает при выполнении сортировки слиянием на линейном массиве, если он реализован его одиноким, но если я помещу его в класс, он выйдет из строя.Я думаю, что это отличный пример того, что я не совсем понимаю о том, как работают классы;возможно в отношении управления пространством имен (?).

См. ниже:

def sort(array):
    print('Splitting', array)
    if len(array) > 1:
        m = len(array)//2
        left = array[:m]
        right = array[m:]

        sort(left)
        sort(right)

        i = 0
        j = 0
        k = 0

        while i < len(left) and j < len(right):
            if left[i] < right[j]:
                array[k] = left[i]
                i += 1
            else:
                array[k] = right[j]
                j += 1
            k += 1

        while i < len(left):
            array[k] = left[i]
            i += 1
            k += 1

        while j < len(right):
            array[k] = right[j]
            j += 1
            k += 1
    print('Merging', array)

arr = [1,6,5,2,10,8,7,4,3,9]
sort(arr)

Создает ожидаемый правильный вывод:

Splitting  [1, 6, 5, 2, 10, 8, 7, 4, 3, 9]
Splitting  [1, 6, 5, 2, 10]
Splitting  [1, 6]
Splitting  [1]
Merging  [1]
Splitting  [6]
Merging  [6]
Merging  [1, 6]
Splitting  [5, 2, 10]
Splitting  [5]
Merging  [5]
Splitting  [2, 10]
Splitting  [2]
Merging  [2]
Splitting  [10]
Merging  [10]
Merging  [2, 10]
Merging  [2, 5, 10]
Merging  [1, 2, 5, 6, 10]
Splitting  [8, 7, 4, 3, 9]
Splitting  [8, 7]
Splitting  [8]
Merging  [8]
Splitting  [7]
Merging  [7]
Merging  [7, 8]
Splitting  [4, 3, 9]
Splitting  [4]
Merging  [4]
Splitting  [3, 9]
Splitting  [3]
Merging  [3]
Splitting  [9]
Merging  [9]
Merging  [3, 9]
Merging  [3, 4, 9]
Merging  [3, 4, 7, 8, 9]
Merging  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Однако я получаю ошибку, когдаЯ пытаюсь использовать эту функцию в классе;я думаю, что это связано с управлением пространством имен.См. Ниже:

class MergeSort(object):

    def __init__(self, array):
        self.array = array

    def sort(self):
        print('Splitting', self.array)
        if len(self.array) > 1:
            m = len(self.array)//2
            left = self.array[:m]
            right = self.array[m:]

            sort(left)
            sort(right)

            i = 0
            j = 0
            k = 0

            while i < len(left) and j < len(right):
                if left[i] < right[j]:
                    self.array[k] = left[i]
                    i += 1
                else:
                    self.array[k] = right[j]
                    j += 1
                k += 1

            while i < len(left):
                self.array[k] = left[i]
                i += 1
                k += 1

            while j < len(right):
                self.array[k] = right[j]
                j += 1
                k += 1
        print('Merging', self.array)

x = MergeSort([1,6,5,2,10,8,7,4,3,9])
x.sort()

Выводит сообщение об ошибке:

Splitting [1, 6, 5, 2, 10, 8, 7, 4, 3, 9]
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-15-89509f86277e> in <module>()
      1 x = MergeSort([1,6,5,2,10,8,7,4,3,9])
----> 2 x.sort()

<ipython-input-14-2bba116f00ce> in sort(self)
     11             right = self.array[m:]
     12 
---> 13             sort(left)
     14             sort(right)
     15 

NameError: name 'sort' is not defined

Мой первоначальный инстинкт, после того как поиск в Google стал менять подпрограммы сортировки (слева) и сортировки (справа) путем добавления префиксаЯ., но это порождает ошибку позиционного аргумента.Хотелось бы комментарий или два о том, что я не понимаю здесь.И приветствует хорошие голоса, если мой вопрос не глупый, и отрицательные голоса, если он есть.

Ответы [ 3 ]

0 голосов
/ 08 июня 2018

Вам нужно позвонить self.sort() в пределах класса.

Большая проблема в том, что ни один из ваших методов или методов класса ничего не возвращает, только печатает, вас это устраивает?

0 голосов
/ 08 июня 2018

Замена компонентов sort(left) и sort(right) функции sort () в моем классе на

leftsorter = MergeSort(left)
leftsorter.sort()
rightsorter = MergeSort(right)
rightsorter.sort()

(Спасибо, abarnert)

При одновременном удалении отладкивывести операторы из кода (спасибо Evgany P), и, избегая повторного использования встроенной функции sort (), чтобы избежать путаницы, у меня есть рабочий класс MergeSort.

class MergeSort(object):

    def __init__(self, array):
        self.array = array

    def merge_sort(self):
        if len(self.array) > 1:
            m = len(self.array)//2
            left = self.array[:m]
            right = self.array[m:]

            leftsorter = MergeSort(left)
            leftsorter.merge_sort()
            rightsorter = MergeSort(right)
            rightsorter.merge_sort()

            i = 0
            j = 0
            k = 0

            while i < len(left) and j < len(right):
                if left[i] < right[j]:
                    self.array[k] = left[i]
                    i += 1
                else:
                    self.array[k] = right[j]
                    j += 1
                k += 1

            while i < len(left):
                self.array[k] = left[i]
                i += 1
                k += 1

            while j < len(right):
                self.array[k] = right[j]
                j += 1
                k += 1

x = MergeSort([3,5,6,2,1,4,10,9,8,7])
x.merge_sort()
x.array

Out []: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Молодцы!

0 голосов
/ 08 июня 2018

Причина, по которой sort(left) не работает, заключается в том, что, как вы и предполагали, вы не можете вызвать метод для self без указания self.Отключение означает, что оно ищет локальное или глобальное имя sort, не находит его и вызывает NameError.

Причина self.sort(left) не работает в том, что API, который вы определилине работает таким образом.Ваш класс принимает список в качестве аргумента конструктора, а затем принимает sort без аргументов, который работает со списком, переданным во время построения.Таким образом, вы не можете вызвать свой собственный sort с другим массивом.Если вы попробуете self.sort(left), вы передадите неправильное количество аргументов, точно так же, как вы вызываете abs(1, 2), и вы получите тот же TypeError.

Вы должны использовать свой API так, как вы его разработали: Создайте новый объект сортировки MergeSort с новым списком, затем вызовите sort для этого нового объекта:

leftsorter = MergeSort(left)
leftsorter.sort()
rightsorter = MergeSort(right)
rightsorter.sort()
...