我正在研究一个红宝石挑战,并且必须编写一个方法来计算一个数字的因子。我在下面遇到了一个解决方案,但我不明白它是如何工作的,特别是else语句中的部分:
def factorial(number)
if number <= 1
1
else
number * factorial(number - 1)
end
end
假设我运行 factorial(5) else语句如何在 number * factorial(number - 1)语句中迭代5 * 4 * 3 * 2 * 1?我知道这似乎应该是显而易见的,但这不适合我。提前感谢帮助。
答案 0 :(得分:5)
这个概念被称为recursion。
factorial(5)评估为
5 * factorial(4)
factorial(4)评估为
4 * factorial(3)
factorial(3)评估为
3 * factorial(2)
factorial(2)评估为
2 * factorial(1)
factorial(1)的计算结果为1,因为1 <= 1
适当地替换值会导致
5 * factorial(4)
5 * 4 * factorial(3)
5 * 4 * 3 * factorial(2)
5 * 4 * 3 * 2 * factorial(1)
5 * 4 * 3 * 2 * 1
答案 1 :(得分:1)
当您从factorial
致电else
时,这是recursion的一个示例:调用您当前所处的功能。这听起来很奇怪,但你真正做的是用新参数调用函数的新副本。这意味着流程从函数顶部重新开始,同时记住完成新副本时返回的位置:
所以你先拨打factorial(5)
,这样做:
def factorial(5)
if 5 <= 1
1
else
5 * factorial(5 - 1)
好吧,在我们继续之前,我们必须调用factorial(5-1)
并使用其返回值来替换该表达式。当然,Ruby在调用之前进行减法,所以当我们进行递归调用时,参数已经只是4:
def factorial(4)
if 4 <= 1
1
else
4 * factorial(4 - 1)
Whups,另一个递归调用。我们再来一次:
def factorial(3)
if 3 <= 1
1
else
3 * factorial(3 - 1)
再次:
def factorial(2)
if 2 <= 1
1
else
2 * factorial(2 - 1)
还有一次:
def factorial(1)
if 1 <= 1
1
抓住你的马! 1实际上小于或等于1,所以这次我们没有点击else
条款。我们只是在factorial(2)
副本中向我们的调用者返回1 - 所以它在2 * factorial(1)
的位置,我们用返回值替换factorial(1)
,这只是1:
2 * 1
end
end
现在返回2给它的调用者,这是factorial(3)
副本。这意味着3 * factorial(2)
变为3 * 2
:
3 * 2
end
end
在factorial(4)
副本中,4 * factorial(3)
变为4 * 6
:
4 * 6
end
end
最后,在我们原来的factorial(5)
电话中回到顶部,5 * factorial(4)
变为“5 * 24:
5 * 24
end
end
这当然是理想的答案120.