Ruby:递归方法

时间:2016-06-29 15:45:56

标签: ruby recursion

def reverse_append(arr, n)  
    return arr if n < 0 
    reverse_append(arr, n-1)
    arr << n
    arr
end 

reverse_append([],4) #=> [0, 1, 2, 3, 4]

我似乎无法理解这种递归方法。它产生一个从0到n的数组。

有人可以向我解释一下吗?

3 个答案:

答案 0 :(得分:8)

  1. 方法reverse_append([],4)称为
  2. 4 >= 0开始,return语句不会被调用。
  3. 调用方法reverse_append([],3)
  4. 3 >= 0开始,return语句不会被调用。
  5. 调用方法reverse_append([],2)
  6. 2 >= 0开始,return语句不会被调用。
  7. 调用方法reverse_append([],1)
  8. 1 >= 0开始,return语句不会被调用。
  9. 调用方法reverse_append([],0)
  10. 0 >= 0开始,return语句不会被调用。
  11. 调用方法reverse_append([],-1)
  12. -1 < 0以来,会返回数组([])。
  13. 我们在调用堆栈中弹出一个级别,n = 0arr = []
  14. arr << narr已退回,现在arr = [0]
  15. 我们在调用堆栈中弹出一个级别,n = 1arr = [0]
  16. arr << narr已退回,现在arr = [0, 1]
  17. 我们在调用堆栈中弹出一个级别,n = 2arr = [0, 1]
  18. arr << narr已退回,现在arr = [0, 1, 2]
  19. 我们在调用堆栈中弹出一个级别,n = 3arr = [0, 1, 2]
  20. arr << narr已退回,现在arr = [0, 1, 2, 3]
  21. 我们在调用堆栈中弹出一个级别,n = 4arr = [0, 1, 2, 3]
  22. arr << narr已退回,现在arr = [0, 1, 2, 3, 4]
  23. 最后,&#34;顶级&#34;方法返回,我们得到了最终结果。

答案 1 :(得分:2)

使用提供的参数逐步完成代码。第一步是检查n&lt;它不是0。如果它不是0反向附加[],3并将该数组附加到该数字,然后返回该数组。

所以它需要数组,在完成处理[], 3[], 2[],1[], 0的步骤后再添加4。因此,第一次调用将成功,只是在数组低于0时返回数组,接下来是0附加,然后是1,然后是2,然后是3,最后是4的原始调用被添加arr << n

答案 2 :(得分:2)

您可以添加一个很好的工具,可以添加到许多名为&#34; Seeing Is Believing&#34;的编辑器中,它可以让您查看代码运行时发生的情况:

def reverse_append(arr, n)  
  return arr if n < 0 # => false, false, false, false, true
  reverse_append(arr, n-1) # => [], [0], [0, 1], [0, 1, 2]
  arr << n # => [0], [0, 1], [0, 1, 2], [0, 1, 2, 3]
  arr # => [0], [0, 1], [0, 1, 2], [0, 1, 2, 3]
end 

reverse_append([], 3) # => [0, 1, 2, 3]

然而,使用&#34; reverse_append&#34;等名称。看起来你应该看到一个以值递减的结果:

def reverse_append(arr, n)  
  return arr if n < 0 # => false, false, false, false, true
  reverse_append(arr, n-1) # => [], [0], [1, 0], [2, 1, 0]
  arr.unshift n # => [0], [1, 0], [2, 1, 0], [3, 2, 1, 0]
  arr # => [0], [1, 0], [2, 1, 0], [3, 2, 1, 0]
end 

reverse_append([], 3) # => [3, 2, 1, 0]

在任何一种情况下,有很多简单的方法可以在不依赖递归的情况下生成这样的数组:

[*0..3] # => [0, 1, 2, 3]
(0..3).to_a # => [0, 1, 2, 3]

[*0..3].reverse # => [3, 2, 1, 0]
(0..3).to_a.reverse # => [3, 2, 1, 0]