给定一个排序的数字列表,我需要找到大于给定数字的最小数字。考虑一下这个清单:
arr=[1,2,3,5,7,11,101,131,151,181,191,313,353,373,383]
假设指定的数字是320.然后,我的方法应返回353,因为353是大于320的最小数字。
我正在尝试使用略微修改的二进制搜索形式;但是在执行时,程序进入无限循环。
def modBinarySearch(arr,x):
l=len(arr)
mid=l/2
if arr[mid]>=x and arr[mid-1]<x:
return arr[mid]
elif arr[mid]>x and arr[mid-1]>x:
modBinarySearch(arr[mid:l],x)
else:
modBinarySearch(arr[0:mid],x)
N=int(raw_input())
arr=[1,2,3,5,7,11,101,131,151,181,191,313,353,373,383]
print modBinarySearch(arr,N)
有人可以指出我做错了吗?
答案 0 :(得分:11)
有一个标准模块bisect
,它已经这样做了:
In [49]: arr[bisect.bisect(arr, 320)]
Out[49]: 353
我认为这应该是搜索排序列表的首选方法。手册中有一些examples。
关于您的实施,存在许多问题:
arr
按升序排列,arr[mid]>x and arr[mid-1]>x
相当于arr[mid-1]>x
,表明您没有写出您的意思最后但并非最不重要的是,递归和所有切片对于此问题完全没有必要。
答案 1 :(得分:6)
如果列表的大小为15,则完全抛弃二进制搜索并使用顺序搜索。
您会发现代码更容易编写,除非您需要每秒执行数百万次,否则顺序解决方案将足够快。
如果 需要坚持使用二进制搜索,那么第一个步骤应该是实际返回递归调用的结果。
答案 2 :(得分:5)
如果arr [mid]和arr [mid-1],两者都大于你的号码,你应该搜索arr [0:mid],你不觉得吗?
elif arr[mid]>x and arr[mid-1]>x:
modBinarySearch(arr[0:mid],x)
else:
modBinarySearch(arr[mid:1],x)
答案 3 :(得分:3)
def modBinarySearch(arr, n):
m = len(arr) / 2
if arr[m] >= n and arr[m - 1] < n:
return arr[m]
elif arr[m] > n and arr[m - 1] > n:
return modBinarySearch(arr[:m], n)
else:
return modBinarySearch(arr[m:], n)
arr = [1, 2, 3, 5, 7, 11, 101, 131, 151, 181, 191, 313, 353, 373, 383]
n = 320
print(modBinarySearch(arr, n))
答案 4 :(得分:2)
python 3.2
next(i for i in arr if i>320)
答案 5 :(得分:1)
bisect module是您的最佳选择:
from bisect import bisect_left, bisect_right
arr=[1,2,3,5,7,11,101,131,151,181,191,313,353,373,383]
def find_lt(a, x):
'Find rightmost value less than x'
i = bisect_left(a, x)
if i:
return a[i-1]
raise ValueError
def find_gt(a, x):
'Find leftmost value greater than x'
i = bisect_right(a, x)
if i != len(a):
return a[i]
raise ValueError
print find_lt(arr,320)
print find_gt(arr,320)
打印
313
353
答案 6 :(得分:0)
如果列表已排序:
x = range(20)
N= 15
for i in x:
if i>N:
print i
break
给予16。
如果使用numpy:
x = np.arange(20)
N = 15
x[x>15][0]
给予16。
如果您正在寻找简单的实施方案,针对您的具体问题,让我重温一下。
答案 7 :(得分:0)
def modBinarySearch(arr,x):
l=len(arr)
mid=l/2
if arr[mid] >= x and arr[mid-1] < x:
return arr[mid]
elif arr[mid]>x and arr[mid-1]>x:
num = modBinarySearch(arr[0:mid],x)
else:
num = modBinarySearch(arr[mid:l],x)
return num
N=int(raw_input('Enter a number: '))
arr=[1, 2, 3, 5, 7, 11, 101, 131, 151, 181, 191, 313, 353, 373, 383]
print modBinarySearch(arr,N)