繁体   English   中英

“Python”中的项目 Euler #2

[英]Project Euler #2 in "Python"

我是这里的绝对初学者。 我在 Python 中尝试了有关 Project Euler 的问题。 你能指出我的代码哪里出错了吗?

Q) 斐波那契数列中的每个新项都是通过将前两项相加而生成的。 从 1 和 2 开始,前 10 项将是:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

通过考虑 Fibonacci 数列中值不超过 400 万的项,找出偶数值项的总和。

def fib(a):
    if ((a==0) or (a==1)):
        return 1
    else:
        return((fib(a-1))+(fib(a-2)))
    r=0
    sum=0
    while (fib(r))<4000000:
        if(((fib(r))%2)==0):
            sum+=fib(r)
            print(sum)

你的代码没有,只是太慢了。 为了解决 Project Euler 问题,不仅您的代码必须正确,而且您的算法必须高效。

您的斐波那契计算非常昂贵 - 也就是说,递归地尝试在 O(2^n) 时间内运行下一个斐波那契数 - 当您想要对限制为 400 万的数字求和时,时间太长了。

Python 中更有效的实现如下:

x = 1
y = 1
z = 0
result = 0

while z < 4000000:
   z = (x+y)         
   if z%2 == 0:
       result = result + z

   #next iteration

   x = y
   y = z

print result

这绝对不是唯一的方法 - 而是另一种方法。

def fib(number):
    series = [1,1]
    lastnum = (series[len(series)-1]+series[len(series)-2])
    _sum = 0
    while lastnum < number:
        if lastnum % 2 == 0:
            _sum += lastnum
        series.append(lastnum)
        lastnum = (series[len(series)-1] +series[len(series)-2])
    return series,_sum

您应该使用生成器功能,这是要点:

def fib(max):

    a, b = 0, 1

    while a < max:

        yield a

        a,b = b, a+b

现在从shell调用这个函数,或者在这个调用fib函数之后写一个函数,你的问题就解决了。我花了7个月才解决这个问题

这可能是最有效的方法。

a, b = 1, 1
total = 0
while a <= 4000000:
    if a % 2 == 0:
        total += a
    a, b = b, a+b  
print (total)

使用递归可能适用于较小的数字,但由于您正在测试最多 4000000 的每个案例,您可能希望将您已经找到的值存储到值中。 您可以在现有答案中查找此算法。

另一种方法是使用比奈公式。 此公式将始终返回第 n 个斐波那契数。 您可以在MathWorld上阅读有关此内容的更多信息。

请注意,偶数斐波那契数在序列中每三个元素出现一次。 您可以使用:

def binet(n):
     """ Gets the nth Fibonacci number using Binet's formula """
     return int((1/sqrt(5))*(pow(((1+sqrt(5))/2),n)-pow(((1-sqrt(5))/2),n)));

s = 0; # this is the sum
i = 3;
while binet(i)<=4000000:
    s += binet(i);
    i += 3; # increment by 3 gives only even-numbered values

print(s);

你也可以试试这个动态程序,对我来说工作得更快

dict = {}
def fib(x):
    if x in dict:
        return dict[x]
    if x==1:
        f = 1
    elif x==2:
        f = 2
    else:
        f = fib(x-1) + fib(x-2)
    dict[x]=f
    return f

i = 1
su = 0
fin = 1

while fin < 4000000:
    fin = fib(i)
    if fin%2 == 0:
        su += fib(i)
    i+=1

print (su)

正如其他答案所指出的,您的代码缺乏效率。 有时,保持尽可能简单是一个好的程序的关键。 这是对我有用的:

    x=0
    y=1
    nextterm=0
    ans=0
    while(nextterm<4000000):
        nextterm=x+y
        x=y
        y=nextterm
        if(nextterm%2==0):
            ans +=nextterm;
    print(ans)

希望这可以帮助。 干杯!

它经过优化并且有效

def fib(n):
    a, b = 0, 1
    while a < n:
        print(a, end=' ')
        a, b = b, a+b
    print()
fib(10000)

以下代码使用两个先前生成的偶数斐波那契数生成下一个偶数斐波那契数。 fib [0]和fib [-1]:

n=int(input("Enter N:"))
fibIter=[0,2]
sum=2
while(True):
    nextFib=fibIter[-1]*4+fibIter.pop(0)
    if(sum+nextFib>n):break
    sum+=nextFib
    fibIter.append(nextFib)
print(sum)

这是基于 Lutz Lehmann 对此答案的评论的稍微更有效的算法(也适用于已接受的答案):

def even_fibonacci_sum(cutoff=4e6):
    first_even, second_even = 2, 8
    even_sum = first_even + second_even
    while even_sum < cutoff:
        even_fib = ((4 * second_even) + first_even)
        even_sum += even_fib
        first_even, second_even = second_even, even_fib
    return even_sum

考虑以下斐波那契数列:

1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, ...

斐波那契数列中的每三个元素都是偶数。

所以上面序列中的偶数是 2, 8, 34, 144, 610, ...

对于偶数n ,以下等式成立:

n = 4 * (n-1) + (n-2)

例子:

  • 34 = (4 * 8) + 2,第三个偶数= (4 *第二个偶数) +第一个偶数
  • 144 = (4 * 34) + 8,第四个偶数= (4 *第三个偶数) +第二个偶数
  • 610 = (4 * 144) + 34第五个偶数= (4 *第四个偶数) +第三个偶数

It's can work with 如果我们知道有多少步,我们将达到4000000。大约30步。

a=1
b=2
list=[a,b]
for i in range (0,30):
    a,b=b,a+b
    if b%2==0:
        list.append(b)
print(sum(list)-1)

调整jackson-jones 答案以找到低于 400 万的偶数值斐波那契项的总和。

# create a function to list fibonacci numbers < n value
def fib(n):
    a, b = 1, 2
    while a < n:
        yield a
        a, b = b, a+b

# Using filter(), we extract even values from our fibonacci function
# Then we sum() the even fibonacci values that filter() returns 
print(sum(filter(lambda x: x % 2 == 0, fib(4000000))))

结果是 4613732。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM