【问题标题】:Efficiently find index of smallest number larger than some value in a large sorted list在大型排序列表中有效地找到大于某个值的最小数字的索引
【发布时间】:2018-12-05 06:06:55
【问题描述】:

如果我有一个长长的排序数字列表,并且我想找到大于某个值的最小元素的索引,有没有比在整个列表上使用二分查找更有效的方法?

例如:

import random
c = 0
x = [0 for x in range(50000)]

for n in range(50000):
    c += random.randint(1,100)
    x[n] = c

找到小于某个数字的 x 中最大元素的位置的最有效方法是什么,z

我知道你已经可以做到了:

import bisect
idx = bisect.bisect(x, z)

但是假设这会被执行很多次,还有比二分查找更有效的方法吗?由于列表的范围很大,创建一个包含所有可能整数的字典会占用太多内存。是否可以创建一个较小的列表,例如每 5000 个数字,并使用它来加快查找大列表的特定部分?

【问题讨论】:

  • 在不牺牲内存或应用额外约束的情况下,您可能无能为力来改进理论上的运行时功能。可以出现在列表中的值的预期范围是多少?它的预期尺寸是多少?你要搜索多少个值,在第一次搜索之前你知道所有的值吗?本文详细介绍了一种多键二分搜索的方法,您可能想看看:researchgate.net/publication/…

标签: python python-3.x list binary-search


【解决方案1】:

如果这可以成为解决方案,您可以尝试吗? 生成列表需要很长时间,但报告结果似乎很快。

给定列表:

import random
limit = 50 # to set the number of elements
c = 0
x = [0 for x in range(limit)]

for n in range(limit):
    c += random.randint(1,100)
    x[n] = c
print(x)

由于它是一个排序列表,您可以使用 for 循环检索值:

z = 1600 # reference for lookup

res = ()
for i, n in enumerate(x):
  if n > z:
    res = (i, n)
    break

print (res) # this is the index and value of the elements that match the condition to break
print(x[res[0]-1]) # this is the element just before

【讨论】:

  • 我看不出这会比只使用bisect 更有效。遍历列表平均为 O(N/2)(假设概率相等),平分平均为 O(lg N)
  • @C.J.Jackson,我在列表limit = 500000 上使用timeit 运行基准测试50 次,以寻找列表末尾的元素(z = x[-10])。在我的机器上,for 循环比bisect 略为faster(1.8693751199999995 s 与 1.8854608779999997 s)。
猜你喜欢
  • 2018-06-27
  • 2012-03-05
  • 2012-11-20
  • 2013-06-07
  • 2010-10-20
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多