Python递归二进制搜索函数不工作,但无法找到原因

oyt4ldly  于 2023-04-19  发布在  Python
关注(0)|答案(5)|浏览(121)

这是我第一次在这里发帖。我得到了一个递归二进制搜索函数,它应该可以工作。但不是。它有一个if条件,使用'or'逻辑运算符来测试一个键是否在输入数组的边界之外。这似乎是问题的根源。if条件在我的递归函数之外工作,但似乎在它内部不工作。它'这很可能是一个小问题,但我看不出这是什么问题

A = [31,48,59,62,71,75,81]
 L=0
 R=len(A)-1
 key = 71

 def recur_binary_search(A, L, R, key):
   if key < A[L] or key > A[R]:
     return -1
   M = (L + R) // 2
   if key < A[M]:
     return recur_binary_search(A,L,M-1,key)
   elif key > A[M]:
     return recur_binary_search(A,L,M+1,key)
   else:
     return M

 print( recur_binary_search(A, L, R, key))
 # my code keeps returning -1 rather than the correct value, 4.

我期望输出为4,但我总是得到一个返回值-1。这似乎是由这个if条件引起的

if key < A[L] or key > A[R]:
    return -1

但是,我只是不明白if条件如何在函数开始时计算为true。我的函数可以看到A[L]是31。它可以看到A[R]是81(通过print语句验证),它可以看到键。键是71。
那么,如果评估为真,这是怎么回事呢?正如我所说,我确信这是一个小问题,但我看不出它是什么。

bejyjqdl

bejyjqdl1#

嘿,你们好,我找到问题了。谢谢你们的帮助。我在第二次递归调用的时候把边界搞砸了。(当我意识到的时候,我差点打了自己一巴掌。哈哈)

def recur_binary_search(A, L, R, key):
  if key < A[L] or key > A[R]:
    return -1
  else: 
   M = (L + R) // 2
  if key < A[M]:  
     return recur_binary_search(A,L,M-1,key)
  elif key > A[M]:    
    return recur_binary_search(A,M+1,R,key) # the fix
  else:
    return M
vuv7lop3

vuv7lop32#

它返回-1而不是4的原因是因为or运算符用于布尔型if语句。(key < A[L]key > A[R])为真。如果为真,则if语句将继续完成它后面的代码(return -1)。如果为false,则if语句将为break。如果您希望检查多个函数,则必须添加elif或另一个if

vddsk6oq

vddsk6oq3#

试试这个:

A = [31,48,59,62,71,75,81]
key = 71

  
def recurs_binary_search(A,L,R,key):
    if L<=R:
        M=(L+R)//2
        if key<A[M]:
            return recurs_binary_search(A,L,M-1,key)
        elif key>A[M]:
            return recurs_binary_search(A,M+1,R,key)
        else:
            return M
    else:
        return -1
 

recurs_binary_search(A,0,len(A)-1,key)
4
ee7vknir

ee7vknir4#

看来你的逻辑在你递归的时候有点走偏了。当你发现key < A[M],那么(按照您提供的代码),您需要返回recur_binary_search(A, L, M-1, key),因为您希望将right值设置为 middle-1。类似地,如果找到key > A[M],则需要返回recur_binary_search(A,M-1,R,key),因为需要将left值设置为 middle-1
你现在的通用算法只是修改了你的right值,这就是为什么你总是返回-1。希望这能让你深入了解如何正确地执行递归二进制搜索(同时仍然坚持你发送的代码的一般形式)。如果你需要任何进一步的澄清,让我知道。

zaqlnxep

zaqlnxep5#

你说你用打印来验证你的输入;那么我建议在函数的开头添加一个print语句来查看到底发生了什么……

[...]
def recur_binary_search(A, L, R, key):
  print(f"{L=}, {R=}, {key=}, {A[L]=}, {A[R]=}, {(L + R) // 2=}")
  if key < A[L] or key > A[R]:
    return -1
[...]

...给...

L=0, R=6, key=71, A[L]=31, A[R]=81, (L + R) // 2=3
L=0, R=4, key=71, A[L]=31, A[R]=71, (L + R) // 2=2
L=0, R=3, key=71, A[L]=31, A[R]=62, (L + R) // 2=1
-1

所以你的A[M]永远不会是71你不会得到你期望的4,因为M永远不会是4。
这应该是一个足够的提示,并回答你的问题的“看看为什么”......我不想破坏解决方案-祝你好运,玩得开心!

相关问题