四百万以下的斐波那契数

4 投票
10 回答
4010 浏览
提问于 2025-04-16 01:26

可能重复的问题:
用更Pythonic的方式找出斐波那契数列的程序。

嘿,我在尝试写一个脚本,目的是计算“斐波那契数列”中所有小于400万的偶数项的总和。

Fibonacci1 = 1
Fibonacci2 = 2
a = 2
i = 4
for i in range(1,4000000):
 Fibonacci1 = Fibonacci1 + Fibonacci2
 if Fibonacci1 % 2 == 0:
  a = a + Fibonacci1
 Fibonacci2 = Fibonacci1 + Fibonacci2
 if Fibonacci2 % 2 == 0:
  a = a + Fibonacci2
print a
raw_input()

本来应该不到一分钟就能完成,但我却花了一整晚,结果还是没解决!


编辑:抱歉,大家,我误解了问题。我以为是要把所有小于400万的偶数项加起来!但其实是要加所有小于400万的偶数项。

有效的代码(不到一秒就完成):

Fibonacci1 = 1
Fibonacci2 = 2
a = 2
while a < 4000000:
 Fibonacci1 = Fibonacci1 + Fibonacci2
 if Fibonacci1 % 2 == 0:
  a = a + Fibonacci1
 Fibonacci2 = Fibonacci1 + Fibonacci2
 if Fibonacci2 % 2 == 0:
  a = a + Fibonacci2
print a
raw_input()

10 个回答

3

你可能会对整数序列在线百科全书感兴趣!

你可以通过名称或序列来搜索信息。

如果你搜索0, 2, 8, 34或者'偶数斐波那契',你会被引导到序列A014445

在这里,你会找到很多信息,包括公式,
从这些信息中编写一个生成器,直接生成偶数斐波那契数是很简单的。

def evenfib():
    """ Generates the even fibonacci numbers """
    a, b = 2, 0
    while True:
        a, b = b, a+4*b
        yield a  
25

你的代码有几个问题:

  • 你在循环中执行了四百万次,而不是等到某个条件成立。
  • 你的循环体内有重复的代码。

大多数人在学习Python时,只接触到命令式编程。这并不奇怪,因为Python本身就是一种命令式语言。不过,Python也支持一定程度的函数式编程,我认为在这种练习中,使用函数式编程的方法会更有启发性。

首先,定义一个生成器,用来生成所有的斐波那契数:

def fib():
    a = b = 1
    while True:
        yield a
        a, b = b, a + b

要使用这个生成器,我们可以从itertools模块导入一些有用的函数。要打印前几个数字,可以使用 islice

from itertools import ifilter, islice, takewhile

for x in islice(fib(), 5):
    print x
1
1
2
3
5

如果只想找出偶数,可以使用 ifilter 来生成一个新的生成器:

def is_even(x):
    return x % 2 == 0

evenfibs = ifilter(is_even, fib())

for x in islice(evenfibs, 5):
    print x
2
8
34
144
610

要从生成器中获取数字,直到某个数字超过四百万,可以使用 takewhile

for x in takewhile(lambda x: x < 4000000, evenfibs):
    print x

要解决这个问题,你可以使用 sum:

sum(list(takewhile(lambda x: x < 4000000, evenfibs)))

我希望这能表明,函数式编程的方法并不难,而且在解决某些类型的问题时,更加优雅。

2

这个循环的条件写错了,应该像这样:

while True:
    Fibonacci1 = Fibonacci1 + Fibonacci2
    if Fibonacci1 % 2 == 0:
        if a + Fibonacci1 > 4000000:
            break
        a = a + Fibonacci1
    Fibonacci2 = Fibonacci1 + Fibonacci2
    if Fibonacci2 % 2 == 0:
        if a + Fibonacci2 > 4000000:
            break
        a = a + Fibonacci2

撰写回答