在编写BinarySearch程序时,我编写了程序:
def binary_search(array, x, low=0, high=None):
if high is None:
high = len(array)
while low < high:
mid = (low+high)//2
midval = array[mid]
if midval < x:
low = mid+1
elif midval > x:
high = mid
else:
return mid
return -1
当我提出以下内容时:
binary_search([1,2,2,3],2)
程序给出的输出是
2
但是,我希望程序将输出的第一个整数'x'的索引作为输出。所以在前面的例子中它将是'1'而不是'2'。关于如何改变这个的任何想法?
答案 0 :(得分:0)
给定[1,2,2,3]
,第一次运行评估第mid = (low+high)//2
行:
mid = (0 + 4) // 2 ==> 2
比array[mid]
满足条件(其值正好为2),返回的索引是mid(2)。
if midval < x:
...
elif midval > x:
...
else:
return mid
答案 1 :(得分:0)
您需要删除提前退出(最终else
条件),将前一个elif
替换为else
;只有当循环终止时,你是否测试相等性并选择返回找到的索引,如果找不到则-1
:
def binary_search(array, x, low=0, high=None):
if high is None:
high = len(array)
while low < high:
mid = (low+high)//2
if array[mid] < x:
low = mid+1
else:
high = mid
return -1 if low >= len(array) or array[low] != x else low
以这种方式行事也是一个好主意,因为通常情况下,您不希望每个循环执行多次比较(<
和>
每个都会调用比较,这可能很昂贵,具体取决于类型);每个循环简化为一个非数字比较可以节省时间(并且通常运行得更快; Python库通常实现<
和==
,并使用包装器来实现{{1}方面的其他比较器}和<
,使它们变慢。)
这实际上是==
在its pure Python implementation中的作用;它与你的代码几乎完全相同。它需要更长的时间,因为它更有可能采取完整的bisect.bisect_left
步骤来识别值的最左边的实例,但增量成本通常会很小,除非您的输入很多重复的值。