簡體   English   中英

數組的三路分區

[英]Three way partitioning of an array

我正在嘗試使用 python 實現給定數組的三向分區。

我的看法:

def partition3(alist, lower, heigher, size):
    start = 0
    end = size-1
    for i in range(size):
        if alist[i] < lower:
            alist[i], alist[start] = alist[start], alist[i]
            start = start+1
        elif alist[i] > heigher:
            alist[i], alist[end] = alist[end],alist[i]
            end = end - 1
        else:
            pass
    return alist

def sort(alist, low, high):
    return partition3(alist, low, high, len(alist))

print sort([1, 14, 5, 20, 4, 2, 54, 20, 87, 98, 3, 1, 32], 10, 20)

預期的結果應該是,1) 所有小於 lowRange 的元素都排在第一位。 2) 在 lowVal 到 highRange 范圍內的所有元素都緊隨其后。 3) 所有大於 highRange 的元素都出現在最后。

這必須在同一個數組中完成,不應該有三個數組。

輸入:列表、lowRange 和 highRange。 但我得到,

[1, 5, 4, 2, 14, 20, 32, 54, 87, 98, 3, 1, 20]

在我在這里缺少的東西上需要幫助。 提前致謝

那么你可以做這樣的事情(不是最佳的,當然有更好的方法):

from itertools import chain
def sort_list_ranges(input_list, low, high):

    sorted_list = [[] for _ in range(3)]

    for elem in input_list:
        if elem < low:
           sorted_list[0].append(elem)
        elif elem > high:
           sorted_list[2].append(elem)
        else:
           sorted_list[1].append(elem)

    print [item for sublist in sorted_list for item in sublist]

它將為您提供一個列表,其中包含低於“低”、中等范圍和高於“高”的值。

def partition3(alist, lower, heigher):    
    n = len(alist)
    i, j, k = 0, 0, n
    while j < k:
        if alist[j] < lower:
            alist[i], alist[j] = alist[j], alist[i]
            i += 1
            j += 1
        elif alist[j] > heigher:
            k -= 1
            alist[j], alist[k] = alist[k], alist[j]                        
        else:
            j += 1
    

def sort(alist, low, high):
    partition3(alist, low, high)
    
a = [1, 14, 5, 25, 4, 2, 54, 17,  19, 87, 98, 3, 1, 32]
sort(a, 10, 20)
print(a)
a = [100, 99, 0, 1]
sort(a, 10, 20)
print(a)

這是基於您的代碼的內容:

def partition3(alist, lower, heigher, size):
    start = 0
    while alist[start] < lower:
        start = start + 1
    end = size-1
    while alist[end] > heigher:
       end = end - 1
    i = start
    while i <= end:
        if (i > start) and (alist[i] < lower):
            alist[i], alist[start] = alist[start], alist[i]
            while alist[start] < lower:
                start = start + 1
        elif alist[i] > heigher:
            alist[i], alist[end] = alist[end], alist[i]
            while alist[end] > heigher:
                end = end - 1
        else:
            i += 1
    return alist

def sort(alist, low, high):
    return partition3(alist, low, high, len(alist))

print sort([1, 14, 5, 20, 4, 2, 54, 20, 87, 98, 3, 1, 32], 10, 20)

它適用於您的示例,但我不能 100% 確定它是正確的。

我認為您的原始版本存在問題

  • 如果 start 指向一個已經較小的元素或 end 指向一個已經較大的元素怎么辦? 那么交換不會解決任何問題,錯誤的順序可能會繼續存在
  • 如果我跑過終點怎么辦? 它將交換回所有正確的上三分之一元素

這也適用於您的示例,但可能不是最佳解決方案。

    def partition3(alist, lower, heigher, size):
        start = 0
        end = size-1
        i=0
        while i < size-1:
            if alist[i] < lower:
                alist[i], alist[start] = alist[start], alist[i]
                start = start+1
                i=i+1
            elif alist[i] > heigher:
                if end < i+1:
                    break
                alist[i], alist[end] = alist[end],alist[i]
                end = end - 1
            else:
                i=i+1
        return alist

    def sort(alist, low, high):
        return partition3(alist, low, high, len(alist))

    print sort([1, 14, 5, 20, 4, 2, 54, 20, 87, 98, 3, 1, 32], 10, 20)

輸出:[1, 5, 4, 2, 1, 3, 14, 20, 20, 98, 87, 32, 54]

謝謝@PaulPanzer,結束 < i+1 的 if 語句必須是第一個

暫無
暫無

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

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