Python 为什么赢了';t蟒蛇赢了';你不会做很多递归吗?

Python 为什么赢了';t蟒蛇赢了';你不会做很多递归吗?,python,recursion,fibonacci,Python,Recursion,Fibonacci,我在做Euler问题项目,我在做第二个。问题是: 斐波那契序列中的每个新项都是通过将前两项相加生成的。从1和2开始,前10个术语将是: 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ... 通过考虑Fibonacci序列中值不超过400万的项,找出偶数值项之和。 我试图用python解决这个问题。我想我的代码是正确的,但由于某种原因,当我运行它时,n大于或等于27,它会等待一分钟,然后返回0。但是,对于任何26或更低的值,它都可以正常运行。这是我的密码: def fib_

我在做Euler问题项目,我在做第二个。问题是:

斐波那契序列中的每个新项都是通过将前两项相加生成的。从1和2开始,前10个术语将是: 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ... 通过考虑Fibonacci序列中值不超过400万的项,找出偶数值项之和。

我试图用python解决这个问题。我想我的代码是正确的,但由于某种原因,当我运行它时,n大于或等于27,它会等待一分钟,然后返回0。但是,对于任何26或更低的值,它都可以正常运行。这是我的密码:

def fib_seq(n):
    if n == 0:
        return n
    elif n == 1:
        return n
    else:
        return fib_seq(n-1) + fib_seq(n-2)

def get_fib_sum(n):
    x = n
    sum = 0
    for i in range(n):
        if fib_seq(x) > 4000000:
            pass
        elif fib_seq(x) % 2 == 0:
            pass
        else:
            sum += fib_seq(x)
            x = i
    return sum

print get_fib_sum(27)

有没有办法解决这个问题,或者至少让它工作起来?如果有区别,我使用的是Wing IDE 101学生版。

在您的循环中,您使用的是
fib_seq(x)
,应该是
fib_seq(I)

此外,如果您想进一步减少时间,可以使用记忆技术

def fib_seq(n):
    if n == 0:
        return n
    elif n == 1:
        return n
    else:
        return fib_seq(n-1) + fib_seq(n-2)

def memoize(fn, arg):
 memo = {}
 if arg not in memo:
  memo[arg] = fn(arg)
  return memo[arg]


fibm = memoize(fib_seq,27)
print fibm

为什么要使用递归?您的代码正在一次又一次地重新计算整个fibonnaci序列。。。代码只需要偶数项的和。不需要递归。在伪代码中:

t1 = 1
t2 = 2;
sum = 2;
do {
   t3 = t1 + t2;
   if (t3 is even) {
      sum += t3;
   }
   t1 = t2;
   t2 = t3;
} while (t2 <= 4000000)
t1=1
t2=2;
总和=2;
做{
t3=t1+t2;
如果(t3为偶数){
总和+=t3;
}
t1=t2;
t2=t3;

}虽然(t2它做了大量的递归,这就是为什么它需要这么长时间


get_fib_sum()
将在一个循环中计算
fib_seq(27)
,该循环执行大量递归并需要一段时间。因为
fib_seq(27)的结果
大于4000000它将永远不会向
总和添加任何内容,最终返回0。

斐波那契序列经常被用作如何编写递归代码的示例,这是荒谬的,因为它有一个非常直接的迭代解:

def fib(n):
    if n < 2:
        return n
    else:
        a, b = 1, 1
        for _ in range(2, n):    # O(n)
            a, b = b, a+b
        return b
这非常有用,因为
T**n
可以在
O(log(n))
步骤中计算

(另一方面,转移矩阵对数的特征向量导致解析解

phi = (1 + 5**0.5) / 2     # golden ratio
fib(n) = round(phi**n / 5**0.5, 0)
但这不是我要说的。)

看看用奇数或偶数产生的术语,你会发现

n:        0,    1,    2,    3,    4,    5,    6,    7,    8, ... 
f(n):     0,    1,    1,    2,    3,    5,    8,   13,   21, ...
e/o:   even,  odd,  odd, even,  odd,  odd, even,  odd,  odd, ...
因此,您需要的是
fib(0)+fib(3)+fib(6)+……
,而计算
T**3
将为您提供直接从一个项到另一个项逐步计算所需的系数


其余部分留给读者作为练习;-)

您不应该调用
fib_-seq(i)
,而不是
fib_-seq(x)
?@Kevin现有答案是注释,您的注释就是答案。另一个提示:
sum()
是python中的内置函数。您不应该使用
sum
作为变量名,因为它可能会导致令人困惑的错误。请使用
functools.lru\u cache
装饰器,而不是自己实现它。我尝试运行原始代码,以了解其速度慢的原因。get_fib_sum(27)将调用fib_seq()超过3400万次。@HåkenLid我更新我的答案,你应该在循环中使用
fib_seq(I)
而不是
fib_seq(x)
n:        0,    1,    2,    3,    4,    5,    6,    7,    8, ... 
f(n):     0,    1,    1,    2,    3,    5,    8,   13,   21, ...
e/o:   even,  odd,  odd, even,  odd,  odd, even,  odd,  odd, ...