【问题标题】:recursive binary search in rubyruby 中的递归二分查找
【发布时间】:2019-02-08 21:06:07
【问题描述】:

我一直在学习一些算法,但我找不到我的方法失败的原因。如果您可以查看代码并阐明为什么会发生这种情况。我真的很感激。

我正在尝试编写一种方法,可以递归地对数组进行二进制搜索,到目前为止,这就是我的全部代码。

 def recursive_binary_search(arr, target)
   max_index = arr.length - 1
   mid_index = max_index / 2

   if arr[mid_index] > target
     new_arr = arr[0..(mid_index - 1)]
     recursive_binary_search(new_arr, target)
   elsif arr[mid_index] < target
     new_arr = arr[(mid_index + 1)..max_index]
     recursive_binary_search(new_arr, target)
   else
     return mid_index
   end
 end

我不断收到的错误是undefined method '&gt;' for nil:NilClass

【问题讨论】:

  • 如果您去掉粘贴代码中的行号,这样我们就可以在此基础上构建并制定解决方案,而不必这样做。
  • 请记住,在尝试解决此类问题时,通常最好先创建一个或多个测试用例,然后再编写代码。您的测试用例有助于定义您尝试解决的问题的参数,并确定您何时有解决方案。
  • arr 的示例、target 的示例以及相关的预期输出可以帮助人们给出答案。
  • 这里有一些关于问题构建的建议。 1. 首先用文字陈述你的问题(把你的前两段颠倒过来)。 2. 读者可能希望运行您的代码,无论是否修改。第一步是剪切和粘贴。这里需要第二步来删除行号。最好只显示代码,不要显示行号、IRB 提示等。 3. 如果您给出一个导致您提到的异常的示例,那将会很有帮助...
  • ...当你给出一个例子时(更一般地),让一切都成为一个有效的 Ruby 对象(例如,没有...(etc.),让例子尽可能简洁,为每个输入分配一个变量对象(例如,arr = [1,2,3]),因此读者可以在答案和 cmets 中引用这些变量而无需定义它们,并显示所需的结果(作为 Ruby 对象)。

标签: ruby recursion binary-search


【解决方案1】:

我无法重现 OP 报告的异常(因为问题中没有给出产生异常的数据),但主要问题是,因为 max_index 是从 arr 计算的,而 @ 987654323@不断变小,方法返回的索引与初始数组arr中正确的索引无关。

例如,假设arr = [1,2,3,4,5,6]target = 6。在这种情况下,该方法将返回0(而不是5)作为目标元素的索引。这是因为arr 会逐渐变为arr[3..6]arr[4..6]arr[5..6]arr[6],此时将返回索引0

这是编写方法的一种方式,使用case 语句。该方法假定targetarr 的一个元素,并且(根据二进制搜索的要求)arr 的元素是按从小到大的顺序排列的。

def recursive_binary_search(arr, target, min_index=0, max_index=arr.size-1)
  mid_index = (min_index+max_index)/2
  case arr[mid_index] <=> target
  when  0  # arr[mid_index] == target
    mid_index
  when -1  # arr[mid_index] < target
    min_index = mid_index + 1
    recursive_binary_search(arr, target, min_index, max_index)
  when  1  # arr[mid_index] > target
    max_index = mid_index - 1
    recursive_binary_search(arr, target, min_index, max_index)
  end
end

arr = [1,2,3,4,5,6]

arr.each { |target| puts "#{target}: #{recursive_binary_search(arr, target)}" }
1: 0
2: 1
3: 2
4: 3
5: 4
6: 5

【讨论】:

  • 重现错误:arr = [0,1], target = 2
【解决方案2】:

如果您的数组已排序,您可以尝试以下操作:

def search(arr, target)
 return nil if array.empty?
 
 mid_index = array.length / 2

 case target <=> array[mid_index]
 when -1
   search(array.take(mid_index), target)
 when 0
   mid_index
 when 1
   subs = search(array.drop(mid_index + 1), target)
   subs.nil? ? nil : (mid_index + 1) + subs
 end

end

【讨论】:

    猜你喜欢
    • 2015-12-16
    • 2012-02-16
    • 1970-01-01
    • 2012-12-19
    • 1970-01-01
    • 1970-01-01
    • 2020-11-13
    • 2021-04-08
    • 1970-01-01
    相关资源
    最近更新 更多