簡體   English   中英

在python類中實現合並排序功能,錯誤

[英]Implementing merge sort function in python class, errors

因此,我定義了一個函數,如果該函數是由它的寂寞實現的,則非常適合對線性數組執行合並排序,但是如果將其放入類中,則會出錯。 我認為這是一個很好的例子,說明了我對類的工作方式不太了解。 可能與名稱空間管理(?)有關。

見下文:

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搜索之后,是通過添加前綴self。來更改子例程sort(left)和sort(right),但是這會產生位置參數錯誤。 對於我在這里不了解的內容,我想發表一兩個評論。 如果我的問題不是愚蠢的,那么他們將為獲得良好的選票而歡呼,如果是我的問題,則為他們投反對票。

如您所推測的那樣, sort(left)不起作用的原因是,您必須在未指定self情況下才能對self調用方法。 取消該設置意味着它會查找本地或全局名稱sort ,找不到,然后引發NameError

self.sort(left)不起作用的原因是您定義的API不能那樣工作。 您的類將列表作為構造函數參數,然后進行不帶參數的sort ,該sort對在構造時傳入的列表進行操作。 因此,您無法用其他數組調用自己的sort 如果嘗試self.sort(left) ,則會傳遞錯誤數量的參數,就像調用abs(1, 2) ,並且得到相同的TypeError

您必須按照設計方式使用API​​:使用新列表創建一個新的MergeSort排序器對象,然后對該新對象調用sort

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

用我的類替換sort()函數的sort(left)sort(right)組件

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

(謝謝你)

同時從代碼中刪除調試打印語句(感謝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]

大家做得好!

您需要在該類中調用self.sort()

一個更大的問題是您的函數或類方法都不返回任何內容,僅返回打印內容,您對此感到滿意嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM