Bry*_*mas 3 python binary-search
我正在尝试在Python中编写一个函数,它找到排序列表中的第一个数字,该数字大于我作为参数传递的特定值.我在网上找到了使用简单列表推导来实现这一目的的例子,但出于我的目的,我需要经常在大型列表上执行此操作,因此在线性时间内运行的搜索过于昂贵.
虽然我遇到了一些无法正常工作的边缘情况,但我在编写迭代二进制搜索类函数时遇到了麻烦.顺便说一下,该功能不需要处理列表中没有较大项目的情况.这是我现有的功能:
def findFirstLarger(num, sortedList):
low = 0;
high = len(sortedList) - 1
mid = -1
while True:
print("low: " + str(low) + "\t high: " + str(high))
if (low > high):
print("Ah geez, low is " + str(low) + " and high is " + str(high))
return # debugging, don't want this to happen
if low == high:
return sortedList[low]
else:
mid = (low + high) / 2;
if num == sortedList[mid]:
return sortedList[mid]
elif num > sortedList[mid]:
low = mid + 1
else:
high = mid - 1
Run Code Online (Sandbox Code Playgroud)
我注意到这个功能不起作用的一个案例如下:
>>> somenumbers=[n*2 for n in range(131072)]
>>> somenumbers[-5:]
[262134, 262136, 262138, 262140, 262142]
>>> binsearch.findFirstLarger(262139,somenumbers)
low: 0 high: 131071
low: 65536 high: 131071
low: 98304 high: 131071
low: 114688 high: 131071
low: 122880 high: 131071
low: 126976 high: 131071
low: 129024 high: 131071
low: 130048 high: 131071
low: 130560 high: 131071
low: 130816 high: 131071
low: 130944 high: 131071
low: 131008 high: 131071
low: 131040 high: 131071
low: 131056 high: 131071
low: 131064 high: 131071
low: 131068 high: 131071
low: 131070 high: 131071
low: 131070 high: 131069
Ah geez, low is 131070 and high is 131069
Run Code Online (Sandbox Code Playgroud)
这里的结果是正确的262140,因为这是列表中第一个大于的数字262139.
任何人都可以推荐一个更实用的清洁实现吗?我不认为这会是一个如此深奥的问题,尽管我还没有找到任何解决方案.
ken*_*ytm 20
你试过这个bisect模块吗?
def find_ge(a, key):
'''Find smallest item greater-than or equal to key.
Raise ValueError if no such item exists.
If multiple keys are equal, return the leftmost.
'''
i = bisect_left(a, key)
if i == len(a):
raise ValueError('No item found with key at or above: %r' % (key,))
return a[i]
find_ge(somenumbers, 262139)
Run Code Online (Sandbox Code Playgroud)
您的代码错误,(1)low > high是有效的终止案例.(2)你不应该停下来low == high,例如,当num == 3你的时候它会返回一个不正确的索引somenumbers.
| 归档时间: |
|
| 查看次数: |
8386 次 |
| 最近记录: |