Ruby:递归方法

def reverse_append(arr, n) return arr if n < 0 reverse_append(arr, n-1) arr < [0, 1, 2, 3, 4] 

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

谁可以给我解释一下这个?

  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. 最后,“顶级”方法返回,我们得到了最终结果。

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

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

有一个很好的工具可以添加到许多名为“ Seeing Is Believing ”的编辑器中,它可以让你看到代码运行时发生了什么:

 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] 

但是,使用“reverse_append”这样的名称,您似乎应该看到一个以值递减的结果:

 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]