[英]How to control nil in this binary_search algorithm
我正在阅读《 Grokking算法》一书,并且正在递归地实现binary_search函数,因此,如果该项目在列表中,我的算法将起作用。
有什么建议可以控制我何时失去零?
def recursive_binary_search(list, item)
if list.length == 0
return nil
elsif list.length == 1
print list
if list.first == item
return 0
else
return nil
end
else
low = 0
high = list.length - 1
mid = (low + Float(high - low)/2).round()
guess = list[mid]
if guess == item
return mid
elsif guess < item
return mid + 1 + recursive_binary_search(list[mid+1..-1], item)
else
return recursive_binary_search(list[0..mid-1], item)
end
end
end
my_list = [1, 3, 5, 7, 9]
puts recursive_binary_search(my_list, 100) # => nil
你近了
首先,不需要旋转来计算中间索引。 说啊
mid = list.length / 2
Ruby中的整数除法会截断,因此结果始终是您想要的整数。
第二个递归调用是一个问题。 它可以返回nil。 因此,您需要保存返回值,并且只有在返回值不为nil时才执行索引运算。
最后请注意,由于Ruby自然返回它计算的最后一个值,因此可以省略所有的return
。 这使得函数作为表达式读取,更像Ruby。
def recursive_binary_search(list, item)
if list.length == 0
nil
elsif list.length == 1
if list.first == item
0
else
nil
end
else
mid = list.length / 2
guess = list[mid]
if guess == item
mid
elsif guess < item
result = recursive_binary_search(list[mid+1..-1], item)
if result.nil?
nil
else
1 + result + mid
end
else
recursive_binary_search(list[0..mid-1], item)
end
end
end
唯一需要return
的情况是,在可能进行更多计算的情况下立即退出函数。
最后请注意,尽管这对于学习非常有用,但是在实际的实现中,您应该避免在Ruby中进行尾部递归,因为与某些其他语言不同,不能保证Ruby作为循环将其优化。 由于二进制搜索可以很自然地实现而无需递归调用,因此您应该这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.