class Fibonacci
def calc(n)
return n if n < 2
return calc(n - 1) + calc(n - 2)
end
end
puts Fibonacci.new.calc(40)
>> 102334155
我想弄清楚这个程序。据我所知,如果它不是0或1,它会递归调用calc方法两次,但我不明白它是如何工作来获得序列的正确数字。
我知道这是我缺乏经验的表现,但有人可以向我解释这是如何正确计算纤维序列的吗?它只是没有点击我。
答案 0 :(得分:2)
让我们以n == 3
为例:
首次迭代:n
不是0
或1
,因此保护条款不会成立。所以我们计算calc(2) + calc(1)
。
致电calc(2)
:致电calc(1) + calc(0)
。这两个都满足guard子句,因此分别返回1
和0
。所以这个计算的结果是1
。
致电calc(1)
:保护条款触发并返回1
。
我们现在将两个1
加起来,得到正确的结果2
。
尝试对n
的更高值应用相同的推理,并记住此实现非常浪费,因为它会重复计算相同的值。
答案 1 :(得分:2)
当您无法理解代码正在执行的操作时,您可能不得不使用puts
语句对其进行腌制。对于递归,它还有助于改变缩进以显示方法何时调用自身以及何时返回方法。这是您为代码执行此操作的一种方法。
INDENT = 4
@tabs = 0
def calc(n)
pr_indent
puts "entered calc(#{n})"
if n < 2
pr_indent
puts "returning n=#{n}"
@tabs -= 1
return n
end
pr_indent
puts "calling calc(#{n-1})"
@tabs += 1
m1 = calc(n-1)
pr_indent
puts "calc(#{n-1}) returned m1=#{m1} to calc(#{n})"
pr_indent
puts "calling calc(#{n-2})"
@tabs += 1
m2 = calc(n-2)
pr_indent
puts "calc(#{n-2}) returned m2=#{m2} to calc(#{n-1})"
pr_indent
puts "returning m1+m2=#{m1+m2}"
@tabs -= 1
m1+m2
end
def pr_indent
print "#{' '*(@tabs*INDENT)}"
end
现在执行
calc(4)
导致打印以下内容。我不会提供正在运行的注释,当您在阅读代码时阅读打印内容时,它应该是不言自明的。
entered calc(4)
calling calc(3)
entered calc(3)
calling calc(2)
entered calc(2)
calling calc(1)
entered calc(1)
returning n=1
calc(1) returned m1=1 to calc(2)
calling calc(0)
entered calc(0)
returning n=0
calc(0) returned m2=0 to calc(1)
returning m1+m2=1
calc(2) returned m1=1 to calc(3)
calling calc(1)
entered calc(1)
returning n=1
calc(1) returned m2=1 to calc(2)
returning m1+m2=2
calc(3) returned m1=2 to calc(4)
calling calc(2)
entered calc(2)
calling calc(1)
entered calc(1)
returning n=1
calc(1) returned m1=1 to calc(2)
calling calc(0)
entered calc(0)
returning n=0
calc(0) returned m2=0 to calc(1)
returning m1+m2=1
calc(2) returned m2=1 to calc(3)
returning m1+m2=3
和calc(4)
返回3
。