找到这个解决方案,在python中创建一个 factorial()
函数,但是我无法理解'为什么'它的工作原理。
功能是:
def factorial(x):
if x <= 1:
return 1
else:
return x * factorial(x-1)
我无法理解实际乘法发生的位置?
在我看来,该函数会一直调用自己,直到它变为1,并返回1.有人可以启发我吗?我确定我很遗憾。
答案 0 :(得分:3)
Where
乘法发生: # +-------------------------- HERE .MUL A, B happens
# | | |
# | v v
# | x ( !(x-1) )
# v
return x * factorial(x-1)
# ---------( -1)
# | | <--------------- vvvvvvvvv
# THIS sends recursive call
# to get B-value "down the line"
# while A is waiting to
# to receive B value
# needed for .MUL A, B
# B waits for return value
# from "recusive" call
# to the same function,
# but with off by one
# smaller number
# UNTIL A == 2 | more exactly A { 2 | 1 | 0 }
# B == 1 | B { 1 | 0 | -1 }
# for which case | for which case
# factorial( 1 ) RETs 1 | factorial( B ) RETs 1
# as a terminal state
# without any .MUL
# without any deeper
# level
# recursion
# call
# thus
# "terminal"
# state
# and since this moment, all "waiting" .MUL A, B-s start to get processed
# from back to front
# one step after another
# 1 * 2 * 3 * .. * A
# which is the definition of !A
# Q.E.D.
why
它的工作原理答案 1 :(得分:3)
考虑一些简单的例子:
factorial(1)
这将立即返回1
factorial(2)
x
在我们的第一个范围内是2。 x
,其中factorial(x-1)
为2。
* x-1
为1
。factorial(1)
,这是我们的第一个案例。结果是1
。2
这基本上是这样,对于任何更高的数字我们得到更多的范围,总是用少一个调用阶乘,最终达到1,我们终止并开始返回值。
答案 2 :(得分:3)
编程的一般提示是插入print
语句,以帮助您查看代码运行时发生的情况。当您破坏了要修复的代码时,这尤其有用,但也有助于理解新代码。在这种情况下,请尝试运行以下命令:
def factorial(x):
print "x", x
if x <= 1:
print "base case, returning 1"
return 1
else:
sub_fact = factorial(x-1)
print "factorial(x-1)", sub_fact
result = x * sub_fact
print "return", result
return result
factorial(4)
答案 3 :(得分:2)
假设您调用factorial(3),这就是它的外观。
阶乘(3):
forEach
=?
由于没有值,因此无法返回,请调用factorial(2)
阶乘(2):
return 3 * factorial(2)
=?
由于没有值,因此无法返回,请调用factorial(1)
阶乘(1):
return 2 * factorial(1)
现在冒泡,因为factorial(1)返回1
return 1
= 2 * 1
返回2
factorial(2)
= 3 * 2
返回6
操作结束
答案 4 :(得分:0)
基本上为每次调用阶乘(x)创建堆栈帧,并形成堆栈帧的层次结构。每次调用等待下一次调用的答案,依此类推。最后,当主调用接收到答案时回答答案。
堆栈帧是调用堆栈的一部分,每次调用子例程时都会创建一个新的堆栈帧。因此,在上面的递归Factorial方法中,每次调用方法时都会创建一个新的堆栈帧。堆栈帧用于存储一个例程调用的所有变量。所以,请记住,调用堆栈基本上是一堆堆栈帧。
答案 5 :(得分:0)
是的,因子0和1是1并且没有乘法也没有下一个递归调用。
否则,你必须注意,在我们乘以当前x之前,我们必须从下一个阶乘中得到结果。
因此,递归“进入”自身直到停止条件(当x == 1时)然后结果回升,如下所示:
factorial(5):
(5 *(4 *(3 *(2 *(1*1)))))
- Read it from right to left, which is the order of recursive execution
- Note: (1*1) would not actually be executed because at x==1 recursion stops.
Because of multiplication rule (a*b = b*a) the direction is irrelevant (top to bottom or bottom to top).