Python递归因子函数

时间:2015-09-26 12:59:53

标签: python factorial

找到这个解决方案,在python中创建一个 factorial() 函数,但是我无法理解'为什么'它的工作原理。

功能是:

def factorial(x):
  if x <= 1:
    return 1
   else:
    return x * factorial(x-1)

我无法理解实际乘法发生的位置?

在我看来,该函数会一直调用自己,直到它变为1,并返回1.有人可以启发我吗?我确定我很遗憾。

6 个答案:

答案 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。
  • 我们将进入else块
  • 我们mulitply x,其中factorial(x-1)为2。 * x-11
  • 我们致电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).