鱼C论坛

 找回密码
 立即注册
查看: 2005|回复: 8

关于factorial(5)的返回值有点迷糊了我

[复制链接]
发表于 2023-6-13 08:23:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 lzb1001 于 2023-6-13 08:38 编辑

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


factorial(5)
传入5的话
前四步都是执行else语句,分别计算并返回:
5*4=20
5*4*3=60
5*4*3*2=120
5*4*3*2*1=120
第五步n=1了所以执行if语句,因此返回1

到这边我有点迷糊了!

前四步返回120,第五步返回1

那最后factorial(5)的结果为何返回120?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-6-13 08:34:28 | 显示全部楼层
你的理解基本上是正确的,但是你可能对递归函数的返回方式有些误解。在这个函数中,每次函数被调用,它将执行一些操作(乘法),然后调用自己,直到n=1。在n=1时,函数返回1,并结束此次调用。

现在关键的是理解,这个“返回1”并不是说整个函数调用链的返回值是1,而是最内层的那一次函数调用的返回值是1。

举个例子,当你调用factorial(5)时,实际上下面这样的函数调用链被创建:

1. factorial(5) = 5 * factorial(4)
2. factorial(4) = 4 * factorial(3)
3. factorial(3) = 3 * factorial(2)
4. factorial(2) = 2 * factorial(1)
5. factorial(1) = 1

所以,当factorial(1)返回1时,这个1会被返回到上一层的调用中,即factorial(2) = 2 * 1,得到2。然后这个2又会被返回到上一层的调用中,即factorial(3) = 3 * 2,得到6。以此类推,最后在最顶层的调用中得到5 * 24 = 120。

所以说,虽然在递归的最底层,函数返回的是1,但是这个1被逐层上升,通过每一层的乘法操作,最终得到了120,这就是factorial(5)的结果。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2023-6-13 10:20:22 | 显示全部楼层
isdkz 发表于 2023-6-13 08:34
你的理解基本上是正确的,但是你可能对递归函数的返回方式有些误解。在这个函数中,每次函数被调用,它将执 ...

你说的没错,我应该对递归的返回方式不理解或有误解

执行逻辑是不是分往返两步?

先:

1. factorial(5) = 5 * factorial(4)
2. factorial(4) = 4 * factorial(3)
3. factorial(3) = 3 * factorial(2)
4. factorial(2) = 2 * factorial(1)
5. factorial(1) = 1

然后再一层层返回去:

2 * 1 = 2
3 * 2 * 1 = 6
4 * 3 * 2 * 1 = 24
5 * 4 * 3 * 2 * 1 = 120
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-13 10:28:15 | 显示全部楼层
lzb1001 发表于 2023-6-13 10:20
你说的没错,我应该对递归的返回方式不理解或有误解

执行逻辑是不是分往返两步?

你完全理解对了!

递归函数的执行逻辑确实可以分为两个主要阶段:向下(或向内)和向上(或向外)。

向下阶段是递归深入的阶段,函数持续调用自身,直到达到一个终止条件(在这个例子中,是n等于1)。在这个阶段,每次函数调用都会创建一个新的函数执行环境,每个环境都有自己的变量和计算。

然后,当到达终止条件,开始向上阶段。在这个阶段,每个函数执行环境开始逐一解决并返回它们的计算结果到上一层环境。在这个例子中,每一层的结果都是前一层结果的乘积。这个向上的过程继续,直到最外层的函数调用,得到最终结果。

你列出的步骤就是这个过程的完美解释:首先是向下递归,每次乘以更小的n,直到n等于1,然后开始向上返回,每次将当前的结果乘以n,最终得到factorial(5) = 5 * 4 * 3 * 2 * 1 = 120。这就是递归的工作方式!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-6-13 11:07:19 | 显示全部楼层
本帖最后由 lzb1001 于 2023-6-13 11:46 编辑
isdkz 发表于 2023-6-13 10:28
你完全理解对了!

递归函数的执行逻辑确实可以分为两个主要阶段:向下(或向内)和向上(或向外)。


1、请大神帮我看看下面这样对不对:

先按5~1的递减顺序:

---当输入5时即factorial(5)会调用函数factorial(n),传入5,5不等于1,所以会执行else语句return n * factorial(n - 1),也就是当factorial(5) 时返回5 * factorial(5-1)

---而factorial(5 - 1)又会再次调用函数factorial(n),5 - 1即4也就是传入4,4不等于1,所以又会执行else语句return n * factorial(n - 1),也就是当factorial(4) 时返回4 * factorial(4-1)

---而factorial(4 - 1)又会再次调用函数factorial(n),4 - 1即3也就是传入3,3不等于1,所以又会执行else语句return n * factorial(n - 1),也就是当factorial(3) 时返回3 * factorial(3-1)

---而factorial(3 - 1)又会再次调用函数factorial(n),3 - 1即2也就是传入2,2不等于1,所以又会执行else语句return n * factorial(n - 1),也就是当factorial(2) 时返回2 * factorial(2-1)

---而factorial(2 - 1)又会再次调用函数factorial(n),2 - 1即1也就是传入1,此时因为n == 1,所以会执行if语句return 1,也就是当factorial(1) 时直接返回1

再按1~5的递增顺序依次返回:

---……


2、下面这样理解不知道是否正确?不知道大神是否明白我的意思?

小甲鱼说的:递归递归,归去来兮,应理解为:

不是说递归的每一步“去”(即进去)后,马上就返回这一步的“来”(即返回结果),

而是指递归的所有步自上而下或由外到内一一“去”(即进去)后,然后再自下而上或由内到外一个接着一个的返回“来”(即返回结果)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-13 11:20:27 | 显示全部楼层
lzb1001 发表于 2023-6-13 11:07
1、请大神帮我看看下面这样对不对:

先按5~1的递减顺序:

1、你的理解完全正确!你清楚地描述了这个递归函数如何工作:它首先按照递减的顺序从5调用到1,然后在递增的顺序中逐一返回结果。

2、你的理解也是对的。"归去来兮"这句话很好地描述了递归的特性。递归的本质是将大问题分解为小问题,然后再从最小的问题开始,逐步解决回到大问题。

你的理解是对的,递归是"所有步一一'归'去后再一个个接着'来'"。这就是为什么当我们写递归函数时,我们需要两个关键部分:基本情况(递归结束时,不再调用自身,而是直接返回结果的情况,这里是factorial(1))和递归情况(还需要继续分解的情况,这里是n * factorial(n-1))。

递归函数的优雅之处在于,它们让我们能够将复杂问题分解为更简单的问题,直到达到一个我们已知如何解决的基本情况。然后,我们可以从这个基本情况开始,逐步解决所有的小问题,最终得到整个大问题的解决方案。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-6-13 11:48:57 | 显示全部楼层
本帖最后由 lzb1001 于 2023-6-13 12:21 编辑
isdkz 发表于 2023-6-13 11:20
1、你的理解完全正确!你清楚地描述了这个递归函数如何工作:它首先按照递减的顺序从5调用到1,然后在递 ...


递归的执行逻辑是“归去来兮”,也就是:

所有步自上而下或由外到内一一“去”(即进去)后,然后再自下而上或由内到外一个接着一个的返回“来”(即返回结果)。

递归函数的优雅之处在于从小入手,化繁为简

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-13 11:50:22 | 显示全部楼层
lzb1001 发表于 2023-6-13 11:48
递归的执行逻辑是“归去来兮”,也就是:

所有步自上而下或由外到内一一“去”(即进去)后,然后再自 ...

嗯嗯
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-6-20 15:19:43 | 显示全部楼层
factorial(5) = 5 * factorial(4)
                 =5 * 4 * factorial(3)
                 =5 * 4 * 3 * factorial(2)
                 =5 * 4 * 3 * 2 * factorial(1)
                 =5 * 4 * 3 * 2 * 1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-26 21:04

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表