【问题标题】:deterministic quickselect for ith order statistic python(medians of median approach)第i阶统计python的确定性快速选择(中位数方法的中位数)
【发布时间】:2017-08-21 13:50:27
【问题描述】:

dselect 在 O(n) 时间内找到给定的未排序整数列表(无重复)中的第 i 个顺序统计信息,采用快速排序原则。第 i 个顺序统计量定义为给定列表中排序版本中的第 i 个最小元素。所以一阶统计量将是最小的元素,n阶统计量将是最大的元素,依此类推......

在运行时,我在dselect 函数的末尾得到IndexError: list index out of range 上的return arr[l]。我认为错误的出现是由于我在dselect 函数的列表medians 上的递归调用中将l 硬编码为0。 (第 4 行)

我应该怎么做才能避免这个错误?我应该如何将l 的值放入该递归调用中?这甚至是这个错误的根源吗?如果这是一个愚蠢的问题,请随时指出,我会删除这个问题。我只需要问这个,因为我已经被困了很长一段时间了。谢谢。

def dselect(arr, l, r, i):
    if l < r:
        #finding pivot deterministically
        medians = createMedianList(arr, l, r)
        pivot = dselect(medians, 0, len(medians) - 1, len(medians) // 2) #line4

        pivot = partition(arr, l, r, pivot)
        if pivot + 1 == i:
            return arr[pivot]
        elif pivot + 1 > i:
            return dselect(arr, l, pivot - 1, i)
        else:
            return dselect(arr, pivot + 1, r, i)

    return arr[l]

def partition(arr, l, r, pivot):
    pivotIndex, i = arr.index(pivot), l
    arr[l], arr[pivotIndex] = arr[pivotIndex], arr[l]

    for j in range(l + 1, r + 1):
        if arr[j] < arr[l]:
            i += 1
            arr[i], arr[j] = arr[j], arr[i]
    arr[l], arr[i] = arr[i], arr[l]

    return i

def createMedianList(arr, l, r):
    medians = []
    for i in range(l, (r + 1) - 5 + 1):
        temp = sorted(arr[i:i + min(5, (r - l + 1) - i)])
        medians.append(temp[len(temp) // 2])

    return medians

if __name__ == '__main__':
    arr = [5, 2, 4, 3, 1, -1]
    #arr = list(map(int, open('select.txt').read().splitlines()))
    print(dselect(arr, 0, len(arr) - 1, int(input('Which order 
    statistic to find? '))))

【问题讨论】:

  • createMedianList 应该做什么?
  • @supinf 它创建一个 n/5 中位数列表,其中 n 是输入长度。它通过将给定的输入列表分成 5 个一组,简单地对它们进行排序并在列表中返回它们各自的中值来实现这一点。请 wiki 中位数方法获取更多信息。谢谢。

标签: python algorithm error-handling quicksort implementation


【解决方案1】:

问题是createMedianList 有时会返回一个空列表: 如果l &gt;= r-3 最终会发生,就会发生这种情况。 我建议您向createMedianList 添加一些内容,以确保它不会返回一个空列表。 例如:if medians==[]:medians=[arr[0]] 或类似的东西(取决于你想要中位数的属性)。

【讨论】:

  • 是的!非常感谢!我是如此专注于第 4 行的递归调用,我什至没有想到这一点。我为 l &lt; r - 3 和何时不是创建了 if 条件。我仍然得到错误的答案,但至少我不再得到任何错误。
猜你喜欢
  • 2018-05-29
  • 1970-01-01
  • 2016-04-11
  • 2021-08-24
  • 2017-03-15
  • 1970-01-01
  • 2021-06-11
  • 2021-03-14
  • 2020-05-04
相关资源
最近更新 更多