斐波纳契程序在第40学期后挂起

时间:2017-12-30 16:16:26

标签: python recursion fibonacci

我正在努力解决这个问题

  

Fibonacci序列中的每个新术语都是通过添加前两个术语生成的。从1和2开始,前10个术语将是:   1,2,3,5,8,13,21,34,55,89,......

     

通过考虑Fibonacci序列中的值不超过四百万的项,找到偶数项的总和。

     

链接:https://projecteuler.net/problem=2

以下是我计算斐波那契数的代码:

# fibonacci series
def fib(x):
    if x==0 or x==1:
        return 1                         
    else:
        return fib(x-1) + fib(x-2)

def test_fib(n):
    for i in range (n+1):
        print 'fib of', i, ' = ' , fib(i)

test_fib(41)

然而,该计划在第40学期后挂起。这段代码有什么问题以及如何解决40及以上的问题?

4 个答案:

答案 0 :(得分:4)

斐波那契算法的天真递归实现会非常快。您可以通过以下两种方式解决此问题:

a)切换到迭代版

def fib(x):
    if x==0 or x==1:
        return 1                         
    a = b = 1
    for _ in range(x-1):
        a, b = b, a+b
    return b

这不如递归解决方案优雅,但具有线性时间复杂度。

b)使用memoization:

from functools import lru_cache

@lru_cache()
def fib(x):
    if x==0 or x==1:
        return 1                         
    else:
        return fib(x-1) + fib (x-2)

这是递归解决方案,但有一个"内存"。如果你不得不多次调用该函数,它还有比迭代版本更快的额外好处。

在旧版本的Python(例如2.7)中,lru_cache尚未存在,但您实现的廉价副本足以供我们使用:

def lru_cache():
    # second-order decorator to be a drop-in replacement
    def decorator(fn):
        cache = {}
        def wrapped(*args, **kwargs):
            if args in cache:
                return cache[args]
            val = fn(*args)
            cache[args] = val
            return val
        return wrapped
    return decorator

答案 1 :(得分:1)

  

考虑Fibonacci序列中的值,其值不是   超过四百万

第34学期超过四百万,所以你不需要超过第40学期。问题解决了。

  

斐波那契算法的天真递归实现将会得到   慢得快。您可以通过以下两种方式解决此问题:

第三种方法是使用不是天真的递归解决方案。你原来的一个问题是它的双重递归:

return fib(x-1) + fib(x-2)

让我们将其减少到一次递归:

def fib(n, res=0, nxt=1):
    if n == 0:
        return res
    return fib(n - 1, nxt, res + nxt)

这会让你度过第40个学期,在997年以递归方式触底。如果你需要更进一步,可以考虑@L3viathan的迭代或memoization解决方案,这两者都非常好。

答案 2 :(得分:0)

首先,这是一个有效的Fibonacci数字生成器:

a,b = 0,1
print(a,b)
for x in range(0, 100):
    a,b = b, a + b
    print(b)

接下来你需要做的就是:

a,b = 0,1
print(a,b)
for x in range(0, 100):
    a,b = b, a + b
    c = 0
    if b % 2 == 0:
        c = c + b
        print(c)

c的最后一次迭代是你的答案。

答案 3 :(得分:0)

这将添加您的条款,直到a大于400万:

def fibo(n):
    i = 0
    a = 1
    b = 1
    sumEven= 0
    while i<n and a < 4000000:
        print ("fib of ", i, " = ", a)
        if(a % 2==0):
            sumEven+=a
        a,b = b, b+a
        i+=1
    print("sum of even: ", sumEven)

fibo(50)