我在Python上使用二进制搜索来解决以下问题:你有一个n个正整数的列表:a0,a1,a2,... an-1,按升序排列。
现在,你的朋友会问你问题,每个表格,"这是一个正整数B. B是列表的一部分吗?"
如果B在列表a中,您会说"是"。
您的任务是输出您对任何给定输入说“是”的次数。
1≤n≤10^5,1≤m≤10^ 5且1≤A,B≤10^ 9
我写了以下代码:
n = int(raw_input())
a = [int(x) for x in raw_input().split()]
m = int(raw_input())
answer = 0
lo = 0
hi = len(a) - 1
end = False
for i in range(0, m):
B = int(raw_input())
while (lo <= hi):
mid = int((lo + hi) / 2)
if B == a[mid]:
answer = answer + 1
break
elif B < a[mid]:
hi == mid - 1
elif B > a[mid]:
lo == mid + 1
print answer
我在终端测试了它,它只是从不输出答案,相反,我只是不断地在数字(甚至字母)中写入终端。输入n,a,m和B的第一个值已成功,因为如果我输入一个字母,终端会给我错误信息,但在前4行之后,它只是不响应我输入的任何内容,直到我使用ctrl Z来打破Python。
有人请说明为什么会这样吗?我已经手动测试了这个程序,它应该有用。
谢谢。
答案 0 :(得分:0)
代码的一个问题是@JohnnyMopp评论:你应该使用=
进行赋值,而不是使用==
等于运算符。
另一个问题是每次二进制搜索后都不会重置hi
和low
的值。您应该移动在for循环中初始化这些变量的行:
answer = 0
for i in range(0, m):
B = int(raw_input())
lo = 0
hi = len(a) - 1
while (lo <= hi):
mid = int((lo + hi) / 2)
if B == a[mid]:
answer = answer + 1
break
elif B < a[mid]:
hi = mid - 1
elif B > a[mid]:
lo = mid + 1
print answer
更好的想法是将二进制搜索编写为函数。
在不编写自己的二进制搜索的情况下实现此目的的另一种方法是使用bisect.bisect()
:
import bisect
def bisect_in(l, v):
return v == l[bisect.bisect(l, v)-1]
count = 0
for i in range(m):
B = int(raw_input())
count += bisect_in(a, B)
print count