python百例练习之第二例-函数的递归调用

问题

编写一个程序,可以计算给定数字的阶乘。
假设将以下输入提供给程序:8
然后,输出应为:40320

我所编写的程序

n = int(input('请输入数字:'))  #此处要注意,在获取输入的内容时都默认为是字符串类型,所以要转换为数值型才能在接下来的语句中调用
s = 1    #所s没有初始值,则无法在下面设置自身相乘
for m in range(n):  #利用for循环实现不断相乘,range()函数得到的其实是一个iterable类型,在python里解释为可以迭代的对象,所以可以使用for来遍历产生的结果,使用list()将结果转化为列表类型。
    s *= (m + 1)
print(s)

输入:8
输出结果:40320

原问题答案

def fact(x):      #定义一个功能为计算阶乘的函数
    if x == 0:
        return 1
    return x * fact(x - 1)   #函数递归调用

x=int(input())  #获取输入值,注意转换为数值型
print(fact(x))  #调用fact()函数,传入参数为x

输入:8
输出结果:40320

在该答案中使用了函数的递归调用(这样一看我自己写的答案实在是,,,,,太低端了),那么函数的递归是什么呢?

函数递归调用

函数递归定义:在调用一个函数的过程中直接或间接的调用该函数本身,称之为递归调用。递归调用最多能调用999层,不然会出现栈溢出的问题。

递归分为两个重要的阶段: 递推+回溯
递推:函数不断减少问题规模直至最终的终止条件。(就是按照给定的条件不断地正向推算下去,先不用考虑返回值的问题,因为需要拿到最后一层的返回值才能够进行计算)

以此答案为例,递推就是指: return x * fact(x - 1) 这一句中,按照调用顺序正向推算,直到传入函数的值为(1-1)也就是0,此时符合if条件并执行if条件下的语句,:return 1,获得了最后的一层返回值:1,不再执行下面的调用语句,终止了循环,递推结束。

递推过程分解如下(此部分用于理解代码执行过程),输入8后:

def fact(x):    #这是获得输入后,在函数外开始调用这个函数
    if x == 0:
        return 1
    return 8 * fact(8 - 1)   # fact(8 - 1)是在函数内对函数本身进行第一次调用
    
def fact(x):    
    if x == 0:
        return 1
    return 8 *7* fact(7 - 1)  #7* fact(7 - 1)是调用fact(8 - 1)产生的值,并通过fact(7 - 1)在函数内对函数本身进行第二次调用

def fact(x):    #第三次循环时
    if x == 0:
        return 1
    return 8 *7*6* fact(6 - 1)  #6* fact(6 - 1)是调用fact(7 - 1)产生的值,并通过fact(6 - 1)在函数内对函数本身进行第三次调用
'''往下以此类推'''

return 8 *7*6*5*4*3*2*1 fact(1 - 1)  #为什么只分析到了这里呢?因为在fact(1 - 1)对函数进行调用时,相当于fact(0),在该函数内有条件:当x==0时,就直接返回值:1,语句不再往下执行,所以式子就截止到了这里。

回溯:拿到最终明确的值(就是最底层的值:1)后,返回给上次调用进行处理,直至初始层。(这一部分是反向推算计算值,就是从最底层获得的返回值开始,不断地将获得的值返回给上一级处理,得到最终结果)

回溯过程分解如下(此部分用于理解代码执行过程):

return 8 *7*6*5*4*3*2*1*1 #根据对递推过程的分析,我们得到这个结果式子,最后一个数字1是通过fact(1 - 1)调用函数本身返回的值,也就是我们说的拿到最终明确的值,计算顺序如下
return 8 *7*6*5*4*3*2*1#因为要从最终值开始不断地返回上一级进行计算,所以首先计算1*1并返回计算结果:1,这个式子中的1就是1*1得到
return 8 *7*6*5*4*3*2  #这个式子中的2是通过返回上一级计算也就是2*1得到返回结果2
return 8 *7*6*5*4*6   #这个式子中的6是通过返回上一级计算也就是3*2得到返回结果6
'''再往下以此类推'''
#在这一部分的if语句返回的值为:1,它不会影响计算的结果,所以在做这一类问题的时候都可以考虑使用1作为返回值

注意在Python:
  1、递归调用必须有一个明确的结束条件(参考此例子中的if语句)。
  2、在python中没有尾递归优化(python解释器不支持),递归调用的效率不高。
  3、进入下一次递归时,问题的规模必须降低(在这个例子中我理解为数值是越来越小,循环次数越来越少,函数的处理越来越简单,其他函数中也是同理)。

持续更新中,如果存在哪些问题,希望大家能及时指出,我一定会及时修改

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值