我正在处理一个ruby挑战,必须编写一个方法来计算一个数字的阶乘。我在下面找到了一个解决方案,但我不明白它是如何工作的,特别是else语句中的部分:
def factorial(number)
if number <= 1
1
else
number * factorial(number - 1)
end
end
假设我运行阶乘(5)else语句是如何在数字*阶乘(数字-1)语句中迭代5*4*3*2*1的?我知道这似乎应该是显而易见的,但这不适合我。提前感谢你的帮助。
这个概念被称为递归。
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
从else
调用factorial
时,这是递归的一个示例:从自身调用当前所在的函数。这听起来很奇怪,但你真正要做的是用一个新的参数调用函数的新副本。这意味着流程从函数的顶部重新开始,同时记住完成新副本时返回的位置:
因此,您首先调用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。