递归函数需要有一个退出条件,以防止它们永远运行。您的递归方法的主要部分如下:
seq = fib_seq(num - 1)
seq << seq[-2] + seq[-1]
在 Ruby 中,方法的最后一个表达式被认为是该方法的返回值,所以上面几行等价于:
seq = fib_seq(num - 1)
seq << seq[-2] + seq[-1]
return seq
让我们来看看如果方法只包含这两行会发生什么,num = 4:
call fib_seq(4)
call fib_seq(3)
call fib_seq(2)
call fib_seq(1)
call fib_seq(0)
call fib_seq(-1)
...
显然这会导致无限循环,因为我们没有退出条件。我们总是在第一行再次调用fib_seq,因此代码没有机会到达最后的return 语句。为了解决这个问题,让我们在开头添加这两行:
array = [0, 1]
return array if num <= 2
这些可以简化为:
return [0, 1] if num <= 2
现在让我们看看当我们使用 num = 4 调用方法时会发生什么:
call fib_seq(4)
4 > 2, exit condition not triggered, calling fib_seq(n - 1)
call fib_seq(3)
3 > 2, exit condition not triggered, calling fib_seq(n - 1)
call fib_seq(2)
2 == 2, exit condition triggered, returning [0, 1]!
fib_seq(2) returned with seq = [0, 1]
add 0 + 1 together, push new value to seq
seq is now [0, 1, 1]
return seq
fib_seq(3) returned with seq = [0, 1, 1]
add 1 + 1 together, push new value to seq
seq is now [0, 1, 1, 2]
return seq
FINAL RESULT: [0, 1, 1, 2]
所以看起来这种方法适用于 >= 2 的 num 值:
def fib_seq(num)
return [0, 1] if num <= 2
seq = fib_seq(num - 1)
seq << seq[-2] + seq[-1]
end
还有一个错误:num = 0 和 num = 1 都返回 [0, 1]。让我们解决这个问题:
def fib_seq(num)
return [] if num == 0
return [0] if num == 1
return [0, 1] if num == 2
seq = fib_seq(num - 1)
seq << seq[-2] + seq[-1]
end
稍微清理一下:
def fib_seq(num)
return [0, 1].first(num) if num <= 2
seq = fib_seq(num - 1)
seq << seq[-2] + seq[-1]
end