首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >第二方案欧拉解

第二方案欧拉解
EN

Code Review用户
提问于 2017-12-06 13:28:46
回答 5查看 2.1K关注 0票数 7

从评论中我最感兴趣的是:

  • 代码的性能
  • 全面审查代码结构、样式规则和命名约定。

问题:2

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

代码语言:javascript
运行
复制
import math
import itertools
#----------------------------------------------------------------------------------
def calc_fibonacci_num(n):
    """Calculates the fibonacci number at the given index.

    Arguments:
        type:<int> - Index value of the fibonacci sequence
    Return:
        type:<int> - Fibonacci number at the given index.
    """
    return int(((1 + math.sqrt(5))**n -(1 - math.sqrt(5))**n)/(2**n*math.sqrt(5)))

#----------------------------------------------------------------------------------
def calc_fibonacci_seq(n):
    """Generates the fibonacci sequence with the highest
    value equal to or less then the number provided by the user.

    Arguments:
        type:<int> - Thrshold value for the fibonacci sequence.
    Return:
        type:<arr> - An array holding the fibonacci sequence.
    """
    return [calc_fibonacci_num(x) for x in itertools.takewhile(lambda x: calc_fibonacci_num(x) <= n, itertools.count())]

#----------------------------------------------------------------------------------
def calc_fibonacci_sum(n, d = 0):
    """Calculates the sum of the numbers in fibonacci sequence.
    Filtering of the numbers to be added is controled with the module operator.

    Arguments:
        type:<int> - Thrshold value for the fibonacci sequence.
        type:<int> - Division value for module operation.
    Return:
        type:<int> - The sum of the numbers in the fibonacci sequence.
    """
    if d > 1 :
        return sum(x for x in calc_fibonacci_seq(n) if x % d == 0)      
    return sum(x for x in calc_fibonacci_seq(n))

#----------------------------------------------------------------------------------
def main():

    print(' Fibonacci-seq : {}'.format(calc_fibonacci_seq(4000000)))
    print(' Fibonacci-sum : {}'.format(calc_fibonacci_sum(4000000, 2)))

#----------------------------------------------------------------------------------
if __name__ == "__main__":
    main()
EN

回答 5

Code Review用户

回答已采纳

发布于 2017-12-06 14:13:37

您的代码看起来很好,并且有很好的文档。不管怎样,我有几个建议。

命名

calc_fibonacci_num是这样一个函数的长名称。calc_前缀可能没用,_num也没用。

表达式fibonacci(5)可能足够显式,而不需要其他信息。

同样的注释也适用于其他函数名。

域定义(和默认值)

d=0作为calc_fibonacci_sum的特例似乎有点“不自然”。可以更清楚地解释,d应该是一个严格的正整数。

然后,您只需要给d默认值1,一切都会正常工作。

函数调用二次

return [calc_fibonacci_num(x) for x in itertools.takewhile(lambda x: calc_fibonacci_num(x) <= n, itertools.count())]中,使用相同的参数调用相同的函数两次。您可以通过在print(n)的开头添加一个calc_fibonacci_num来轻松地检查这一点。

解决此问题的一个方法是重写该函数:

代码语言:javascript
运行
复制
def calc_fibonacci_seq(n):
    return itertools.takewhile(lambda x: x <= n, (calc_fibonacci_num(x) for x in itertools.count()))

这修复了另一个问题,即在内存中构建一个实际的列表时,只需要一个生成器来遍历不同的列表。

是生成连续斐波纳契数

的一种更简便的方法

您所使用的公式对于生成n个斐波那契数是相当有效的,而不需要生成之前的所有数字。然而,在我们的例子中,我们确实需要计算它们。因此,天真的解决方案可能会更快。我建议使用以下发电机:

代码语言:javascript
运行
复制
def fibo(f=1, g=1):
    """Yields Fibonacci numbers."""
    while True:
        yield f
        f, g = g, f + g
票数 16
EN

Code Review用户

发布于 2017-12-06 16:15:33

正确性

calc_fibonacci_num没有提到接受的输入范围

代码语言:javascript
运行
复制
>>> calc_fibonacci_num(100)
354224848179263111168L

根据wolframalpha,电话号码是354224848179261915075

浮点算法不够精确,无法处理这一问题。

票数 16
EN

Code Review用户

发布于 2017-12-06 18:00:15

由于Josay已经对代码本身进行了广泛的讨论,请允许我在性能方面再加两分钱。

一些欧拉问题都是针对初学者和有经验的程序员的,第二个问题就是其中之一。初学者像你一样处理这个问题,并按要求逐个实现解决方案。更有经验的程序员模糊地记得一些关于几何级数的内容,并通过首先搜索Fibonacci索引n来实现解决方案,生成一个低于极限M的值:

代码语言:javascript
运行
复制
n = floor(log(M*sqrt(5))/ log((1+sqrt(5)) / 2 ))

(当心:这给了F(n) <= M !)对于具有默认M <= 2^64精度的double来说,它已经足够好了。

到并包含n的偶数斐波纳契指数之和是F(2n + 1) -1 (通过伸缩级数和在https://math.stackexchange.com/questions/1159572/prove-the-sum-of-the-even-fibonacci-numbers进行归纳来证明)。

该方法将F(n)的计算次数减少到一次(或者两次,如果限制为F(n) < M),虽然需要一个大得多的(Python有一个内置的bigint库,因为版本>2.5)才能得到最终的结果,但如果您将F(n)的求值作为矩阵指数来实现,那么计算速度还会更快。

票数 7
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/182146

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档