【一起来刷Python题】——13.解决“斐波那契数列”问题

⭐今天无意中翻出来了一本笔记,上面有高中班主任的留言,写着:谨记,内心爆发的力量足以让自己恐惧,做最真的自己!自己在一旁也写下了一行这样的话:这个世界没用天才,只有不努力的笨蛋。可能是从哪里抄的,可能真的是有感而发....🌈⭐

问题描述:斐波那契数列因数学家列昂纳多·斐波那契以兔子繁殖为例子引入,故又称为“兔子序列”。一般而言,兔子在出生两个月后,就有繁殖能力,一对兔子每个月能生出一对小兔子来。如果所有小兔子都不死,那么一年以后可以繁殖多少对兔子? 

程序代码:

def fib_num(n):
    if n <= 1:
        return n
    else:
        return  fib_num(n-1)+fib_num(n-2)
n = int(input("输入斐波那契数列的第n项\n"))
print("斐波那契数列的第", n, "项是", fib_num(n))

程序思路:

月数与兔子对数关系对照表
月数12345678...
对数1123581321...
        表中数字1,1,2,3,5,8...构成的序列,有十分明显的特点:前面相邻两项之和,构成了后一项。这个特点证明:每个月的大兔子数为上月的兔子数,每个月的小兔子数为上月的大兔子数,某月兔子的对数,等于其前面紧邻两个月的和。                                              注意:在使用上述函数fib_num(n)时,分别设置n的值为998和999进行测试,会发现当n为998时能输出正确答案,但当n大于998时会出现下面的错误:                                                        RecursionError: maximum recursion depth exceeded in comparison                                      这是因为Python设置了递归的深度 的默认限制值,目的是避免耗尽计算机的内存,在Windows系统中,这个默认值是998。                                          

使用Memorization(记忆化)优化递归

        上述基于递归的代码虽然简洁,但是效率比较低。 上面的的实例中,由于递归函数会重复调用很多遍函数,传入相同的参数,得到同样的结果,实际上是重复实现同一个行为,导致效率很低。例如计算f(4)=f(3)+f(2),f(3)=f(2)+f(1),会计算两次f(2)。

        为了提递归算法的效率,我们考虑使用 Memorization (记忆化)技术优化我们的递归算法。Memorization是一种利用缓存来加速函数调用的技术手段,将消耗较大的调用结果存储起来,当再次遇到相同调用时就从缓存读取结果而无须重新计算,这种方法叫做 LRU(least recently used) 缓存算法。Memorization 技术的核心思想就是建立一个散列,然后把递归算法里的计算结果记录下来,如果在循环中发现重复的计算就之间获取结果。

        在Python中,为我们提供了内置的库函数 functools.lur_cache() 来实现 Memorization 功能。函数lru_cache()是一个内置函数缓存装饰器,具体语法如下所示。

@functools.lru_cache(maxsize=128, typed=False)

🔺参数maxsize:指最大缓存多少个调用,如果赋值为None,则表示无限制缓存,且关闭LRU功能。

🔺参数typed:表示当控制函数参数的类型不同时是否单独缓存。当设置为True时,例如 f(3) 和f(3.0)将会区别对待。

程序示例:

import functools
@functools.lru_cache(maxsize=128, typed=False)
def fib_num(n):
    if n <= 1:
        return n
    else:
        return fib_num(n-1)+fib_num(n-2)

n = int(input("输入斐波那契数列的第n项\n"))
print("斐波那契数列的第", n, "项是", fib_num(n))

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花落指尖❀

您的认可是小浪宝宝最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值