【问题标题】:Storing the return value of a recursive function in a variable in ruby将递归函数的返回值存储在ruby中的变量中
【发布时间】:2016-09-09 20:50:49
【问题描述】:

我正在解决一个问题,即在一个总和为特定目标的数组中找到第一对数字。我必须返回最右边的索引首先出现的对。所以说目标是10,在索引1,5[3,7] 索引3,4 上找到的对是[5,5],我必须返回[3,7]。我有递归部分工作,问题是它返回一个哈希,最左边的索引作为键,对作为值。我试图从另一个函数(#sum_pairs)调用这个递归函数,这样我就可以格式化我需要的输出,但是当我这样做并尝试将它存储在变量对中时,它返回的只是一个空哈希,甚至虽然当我从控制台调用它时它会返回完整的哈希。

这是我的代码:

    $starts = [0]

    def sum_pairs(ints, s)
     pairs = find_pairs(ints,s)
     pairs[pairs.keys.min]
    end

    def find_pairs(ints, s)
     sums = {}

     ints.each_with_index do |n, idx|
       next if idx < $starts.last
       right_idx = completes(ints, idx, n, s)

       if right_idx.nil?
        return sums if idx == (ints.length - 1)
        next
      else
       sums[right_idx] = [n, (s - n)]
       $starts << idx
       sums.merge!(sum_pairs(ints[0...right_idx], s))
       sums
      end
     end
    end

    def completes(ints, idx, n, s )
     ints.each_with_index do |num, index|
      next if index <= idx
      return index if num == s - n
     end
     nil
   end

我知道我可以通过迭代来做到这一点,它可能会更有效或同样有效,但我试图用它来更好地理解递归,谢谢!

【问题讨论】:

  • 您能否提供更多示例来说明所需的结果?你说你应该返回最左边元素首先出现的对。你的意思是先出现在索引方面?如果是这样,您不应该返回[5,5],因为索引 1 出现在索引 3 之前吗?
  • 你能显示completes方法的代码吗?
  • 对不起,我想说的是最右边的。只是改变了它并添加了完成方法
  • 产生问题的示例输入也很有用 - 帮助人们重现问题,而不是要求他们猜测

标签: ruby algorithm recursion


【解决方案1】:

我无意冒犯,但我花了一段时间才理解您的代码。当您打算让其他人阅读时,您可能需要更明确地命名您的方法和参数。

作为一个局外人,我花了一段时间才理解整个代码中的s 实际上代表了target_number。注释您的方法以说明如何使用它们以及预期的返回值应该是什么也是一个好主意。

integers = [1,2,3,4,5,6,7,8,9,3,4,5,6,7,8,4,3,2,1]
target_number = 10
$current_index = [0]

def set_right_index(integers, leftmost_index, leftmost_int, target_number)
  integers.each_with_index do |int, i|
    next if i <= leftmost_index
    return i if int == target_number - leftmost_int
  end
  nil
end

def find_pairs(integers, target_number)
  sums = {}

  integers.each_with_index do |int, i|
    next if i < $current_index.max
    # debug = []
    # debug << set_right_index(integers, i, int, target_number)
    right_index = set_right_index(integers, i, int, target_number)

    if right_index.nil?
      return sums if i == integers.length - 1
      next
    end

    sums[right_index] = [int, (target_number - int)]
    $current_index << i
    # sums.merge! sum_pairs(integers[0..right_index], target_number)  #<= calling this returns a `stack overflow error` :P because the methods just keeps calling itself
    sums
  end
end

现在,如果你打电话

find_pairs(integers, target_number)

返回值将如下所示:

{8=>[1, 9],
 7=>[2, 8],
 6=>[3, 7],
 5=>[4, 6],
 11=>[5, 5],
 10=>[6, 4],
 9=>[7, 3],
 17=>[8, 2],
 18=>[9, 1],
 13=>[3, 7],
 12=>[4, 6],
 15=>[6, 4],
 16=>[7, 3]}

你说:

问题是它返回一个以最左边的索引为键的散列,而 对作为值。我试图从另一个调用这个递归函数 函数(#sum_pairs),以便我可以格式化我需要的输出

请准确告诉我so that I can then format the output I need 是什么意思 您希望最终结果如何?

编辑#1

出于调试目的,我将所有结果放在一个数组中,结果如下所示

integers = [1,2,3,4,5,6,7,8,9,3,4,5,6,7,8,4,3,2,1]
target_number = 10

=> [{:left_index=>0, :right_index=>8, :values=>[1, 9]},
 {:left_index=>1, :right_index=>7, :values=>[2, 8]},
 {:left_index=>2, :right_index=>6, :values=>[3, 7]},
 {:left_index=>3, :right_index=>5, :values=>[4, 6]},
 {:left_index=>4, :right_index=>11, :values=>[5, 5]},
 {:left_index=>5, :right_index=>10, :values=>[6, 4]},
 {:left_index=>6, :right_index=>9, :values=>[7, 3]},
 {:left_index=>7, :right_index=>17, :values=>[8, 2]},
 {:left_index=>8, :right_index=>18, :values=>[9, 1]},
 {:left_index=>9, :right_index=>13, :values=>[3, 7]},
 {:left_index=>10, :right_index=>12, :values=>[4, 6]},
 {:left_index=>12, :right_index=>15, :values=>[6, 4]},
 {:left_index=>13, :right_index=>16, :values=>[7, 3]},
 {:left_index=>14, :right_index=>17, :values=>[8, 2]}]

请告诉我您希望最终结果如何,以便我试一试。

【讨论】:

  • 对不起,关于懒惰的命名,它在codewars中是这样写的,我没有花时间正确命名它们。最终输出需要是具有最低键值的哈希元素。我最感兴趣的是如何使用递归来解决这个问题。调用 sums.merge!(#sum_pairs) 时,我没有收到堆栈溢出错误。它返回了正确的值
  • Edit#1 中哈希数组中的最小值是多少? right_index=>5 ?
猜你喜欢
  • 2016-02-04
  • 1970-01-01
  • 2016-11-23
  • 1970-01-01
  • 2015-08-16
  • 1970-01-01
  • 2020-05-05
  • 2015-12-16
  • 2022-11-05
相关资源
最近更新 更多