蓝桥杯 斐波那契数列(python)

蓝桥杯 斐波那契数列(python)

问题描述
Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1。
当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少。

最初看到这个问题,笔者最开始考虑到的是利用递归进行解决,于是有了如下代码

# -*- coding: utf-8 -*-
import sys
def fibonacci(num):
    if num == 0:
        return 0
    if num == 1:
        return 1
    if num == 2:
        return 1
    return (fibonacci(num - 1)+ fibonacci(num - 2))%10007
def main():
    #当递归深度超出999时会进行报错,所以要加上这段代码
    sys.setrecursionlimit(9000000)
    print(fibonacci(int(input())))
if __name__ == '__main__':
    main()
运行结果
10
55

就目前来看这段代码是没有问题的,但是一旦运行比较大的数值运行速度就会很慢引发超时,于是乎这里给出另一种方法

def main():
    num = eval(input())
    lst = [0, 1, 1]
    if num == 0:
        print(0)
        return
    for i in range(2,num):
        lst.append((lst[i - 1] + lst[i])%10007)
    print(lst.pop())
if __name__ == '__main__':
    main()
运算结果:
99999
6415

相比于前者,这段代码运算大数值的运行速度要快很多 (根本不是一个等级)。
那么问题就来了,为什么会产生这种情况呢?
这里一下引用python递归运行过慢的原因及解决方案
python在运行递归的时候,每次用到之前的数值,都会重新计算一次……所以才会这么慢。
于是乎这位答主提出将结果放入缓存提高运行效率,于是乎根据修改可以得到如下代码。

# -*- coding: utf-8 -*-
import sys
from functools import lru_cache
@lru_cache(maxsize=None)
def fibonacci(num):
    if num == 0:
        return 0
    if num == 1:
        return 1
    if num == 2:
        return 1
    return (fibonacci(num - 1)+ fibonacci(num - 2))%10007
def main():
    #当递归深度超出999时会进行报错,所以要加上这段代码
    sys.setrecursionlimit(9000000)
    print(fibonacci(int(input())))
if __name__ == '__main__':
    main()

运行结果:
1500
1945

速度确实有很大的提升但,一旦运行大于1553的数值就无法继续得出结果了。这里贴出
Python 缓存机制与 functools.lru_cache
因为笔者自己学识有限,这里就个人就很难深究下去了,如有大佬,希望可以指点一下。

你可能感兴趣的:(python)