首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >项目Euler #2 ( Fibonacci数之和在400万以下)的更有效解决方案

项目Euler #2 ( Fibonacci数之和在400万以下)的更有效解决方案
EN

Code Review用户
提问于 2014-01-16 20:31:13
回答 4查看 2.6K关注 0票数 7

我想得到一些关于我的代码的反馈。我是在做了一些在线Python课程之后开始编程的。

你能帮助我,跟随我的思路,然后找出我可以更有效率的地方吗?(我看到了其他答案,但它们似乎比所需的复杂,尽管篇幅较短;但也许这就是关键所在)。

问题:

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
fibValue = 0
valuesList = []

a = 0
b = 1

#create list

while fibValue <= 4000000:
    fibValue = a + b
    if fibValue % 2 == 0:
        valuesList.append(fibValue)
    a = b
    b = fibValue

print (valuesList) #just so that I can see what my list looks like after fully compiled

print() #added for command line neatness

print() #added for command line neatness

newTot = 0

for i in valuesList:
    newTot += i
print (newTot)
EN

回答 4

Code Review用户

发布于 2014-01-16 21:19:34

我总是向人们提出这个问题的暗示。看一看序列的前几个数字--我用粗体将偶数设置为:

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

你能看到间隔上的图案吗?你能解释(理想情况下,证明)吗?

既然如此,你能想出一种直接生成斐波那契数的方法吗,而不是为它们过滤?(提示:从(1,2)开始,尝试一步生成(5,8),然后(21,34)等,做一些代数,并想出如何同时应用生成规则的多次迭代。

无论如何,在用数字进行实际计算时,有更优雅的方法。我们可以编写一个生成器,而不是直接要求Python构建一个列表:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def even_fibonacci_up_to(n):
    a, b = 1, 2
    while b <= n:
        yield b # since 2 qualifies, after all.
        # Now calculate the next value.
        # math from the first step goes here when you figure it out!

注意yield关键字的使用。这允许我们将表达式even_fibonacci_up_to(4000000)看作是一种特殊的序列,其元素是按需生成的。与普通函数不同,普通函数只能return一次。)(在生成器中使用return将在到达yielding值时终止整个过程。)

我们可以使用内置的sum函数,而不是循环遍历这个序列来累加数字:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sum(even_fibonacci_up_to(4000000))
票数 7
EN

Code Review用户

发布于 2016-07-24 23:40:54

您的方法不错,尽管它可以被清理,我有一个更快、更直接的建议,比如使用一个简单的类。

  • Knechtel的方法似乎创造了一个近乎无限的循环。
  • Madison的递归方法超过输入40,达到"RuntimeError:最大递归深度超过“。但他们建议的第三种解决方案似乎没有错误地执行,但输出似乎不准确.我相信你只得到了最大的数字,达克。我的也一样。

我认为这是你最好的,最准确的,最简单的(也是最快的给出一个正确的解决方案):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def fib(n):   # return Fibonacci series up to n
    result, a, b = list(), 0, 1 # set variables
    result.append(0) # Initial Fibonacci Zero
    while b < n:
        if b % 2 == 0:
            result.append(b)
        a, b = b, a+b
    return result

def fibSum(n):
    return sum(map(int, fib(n)))

print(fibSum(4000000))

希望这能有所帮助。祝好运!

此外,我建议在打印代码清洁时使用“\n”作为新行,没有必要使用几个打印语句,但我们都是从某个地方开始的,我自己只编写了大约一年的Python程序,但我的背景中也有其他语言,我读了很多书。几个关键注意事项: map允许您轻松地总结一个in /truple列表,您可以使用sum而不是在列表中递增并将其加起来,在“几乎”所有情况下,它应该更快(字符串是一个不同的故事)。再次祝你好运!

我保留了你的国防部2模数是你的朋友。修改内置的周边不是你的朋友,如果你必须这样做,很可能你做错了什么。只是思考的食粮。

基准:

你的守则:

产出: 4613732

运行总时间: 0.000175秒( Python )

总运行时间: 0.000069秒( Pypy )

我的建议:

产出: 4613732

运行总时间: 0.000131秒( Python )

总运行时间: 0.000053秒( Pypy )

编辑:或者,您可以只使用以下内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def fib2(n):
    result, a, b = 0, 0, 1
    while b < n:
        if b % 2 == 0:
            result += b
        a, b = b, a+b
    return result

print(fib2(4000000))

我个人更喜欢让Fibonacci自己来构建一个单一用途类,不管是出于什么原因。显然,它应该稍微快一点,但我还没有测试它。

票数 2
EN

Code Review用户

发布于 2014-01-16 20:51:39

Fibonacci序列是一个非常适合递归解决方案的问题。如果您还没有了解递归,我强烈推荐它,因为它提供了一种全新的方法来看待问题。

要找到第n个Fibonacci数,您可以使用如下所示的内容。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def fibonacci(n):
    if n < 2: return n
    return fibonacci(n-1)+fibonacci(n-2)

fibonacci(10) # returns 55

这个答案之所以如此清晰,是因为它的框架方式和斐波纳契序列是一样的。要找到一个斐波那契数,只需知道前两个。

尽管如此,递归确实引入了一些有趣的问题。要找到第100个斐波那契数,需要花费惊人的时间。这样的问题通常需要缓存才能提高递归的效率。

如果我们从相反的方向来处理这个问题呢?我们可以从底层开始,从上往上爬,而不是从上开始往下走。然后,状态存储在函数的参数中。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def fibonacci(a, b, n):
    if n < 3: return a + b
    return fibonacci(b, a+b, n-1)

fibonacci(0, 1, 10) # returns 55

我希望你喜欢这种递归的味道。如果有什么不清楚的话请告诉我,我很乐意帮忙把事情弄清楚。但是,如果效率是您的目标,那么Python的递归可能不是最好的。

如果递归不是您的问题,或者您打算计算非常大的fibonacci数,您可能需要一个迭代解决方案(实际上,您自己的解决方案非常好)。如果您在寻找小于n的最大fibonacci数,则迭代解决方案工作得特别好。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def fibonacci(n):
    # finds the largest fibonacci number less than n
    a, b = 0, 1
    while(a+b) < n:
        a, b = b, a+b
    return b
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

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

复制
相关文章
Node.js GET、POST 请求是怎样的?
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时,它使 JavaScript 能够在服务器端运行。作为一种强大的后端开发工具,Node.js 提供了丰富的模块和功能,使开发人员能够轻松地构建高性能的网络应用程序。
网络技术联盟站
2023/07/07
7650
http请求中get和post方法的区别
一般我们在浏览器输入一个网址访问网站都是GET请求;再FORM表单中,可以通过设置Method指定提交方式为GET或者POST提交方式,默认为GET提交方式。
用户7880705
2020/11/06
4.3K0
javascript 请求 sse stream,解析结果
比如 目前 openai api 的 stream 返回。 标准的请求sse是 EventSource,但是这个无法像正常post一样,携带数据或者header。若你的接口需要进行鉴权,需要携带header或者body数据,像post请求一样,那么这个EventSource就没法用了。
shirishiyue
2023/05/28
3K0
【OkHttp】OkHttp Get 和 Post 请求 ( 同步 Get 请求 | 异步 Get 请求 | 同步 Post 请求 | 异步 Post 请求 )
【OkHttp】OkHttp 简介 ( OkHttp 框架特性 | Http 版本简介 ) 【OkHttp】Android 项目导入 OkHttp ( 配置依赖 | 配置 networkSecurityConfig | 配置 ViewBinding | 代码示例 ) 【OkHttp】OkHttp Get 和 Post 请求 ( 同步 Get 请求 | 异步 Get 请求 | 同步 Post 请求 | 异步 Post 请求 )
韩曙亮
2023/03/29
16.6K0
在GET、POST请求中,常见的几种传参格式
一: 在GET请求中,常见的几种传参格式包括: 1:查询字符串(Query String): 在URL中使用?符号将参数附加到URL末尾,多个参数之间使用&符号分隔。例如: GET /api/use
王小婷
2023/09/21
20.5K1
PHP简单的Curl的Get请求和Curl的Post请求和file_get_contents的Get请求获取接口JSON数据
PHP携带Cookie用Curl进行Post或Get请求获取数据 PHP全能Curl请求 /** * curl发送HTTP请求方法 * @param $url * @param string $method * @param array $params * @param array $header * @param int $timeout * @param bool|false $multi * @return mixed * @throws Exception */ function
骤雨重山
2022/01/17
2.2K0
记录 RestTemplate 中的 GET 请求
Spring 提供的用于访问 Rest 服务的客户端,RestTemplate 提供了多种便捷访问远程 Http 服务的方法,能够大大提高客户端的编写效率。它的堂兄:Http Client。(有了它,堂兄就用的少了)
子乾建建-Jeff
2020/06/29
2.2K0
记录 RestTemplate 中的 GET 请求
get和post请求的区别
网上也有文章说:get和post请求实际上是没有区别,大家可以自行查询相关文章(参考文章:https://www.cnblogs.com/logsharing/p/8448446.html,知乎对应的问题链接:get和post区别?)!我下面给出的只是一种常见的答案。
崔笑颜
2020/06/08
1.2K0
关于GET和POST请求
网上看了一篇关于这两种请求的区别,感觉和之前看到的不太一样。 大众版: 1. GET使用URL或Cookie传参。而POST将数据放在BODY中。 2. GET的URL会有长度上的限制,则POST的数据则可以非常大。 3. POST比GET安全,因为数据在地址栏上不可见。 分析: 对于第一个: GET和POST与数据如何传递没有关系      GET和POST是由HTTP协议定义的。在HTTP协议中,Method和Data(URL, Body, Header)是正交的两个概念,也就是说,使用哪个Method
小端
2018/04/16
1K0
请求类型 GET 和 POST 的区别
如果像 HTML 表单那样 POST 数据,要用 setRequestHeader() 来添加 HTTP 头,然后在 send() 方法中规定所要发送的数据
Leophen
2019/08/23
9770
GET 和 POST 请求方式的区别
GET 请求方式传输的数据大小不能大于 2KB,而 POST 请求方式传输的数据大小没有限制
很酷的站长
2022/12/16
9510
GET 和 POST 请求方式的区别
Http:GET和POST请求的区别
GET和POST请求的区别 GET请求 GET /books/?sex=man&name=Professional HTTP/1.1 Host: www.wrox.com User-Ag
心跳包
2020/08/31
1.4K0
获取URL地址中的GET参数
/*-----------------实现1--------------------*/ function getPar(par){ //获取当前URL var local_url = document.location.href; //获取要取得的get参数位置 var get = local_url.indexOf(par +"="); if(get == -1){ return false; } //截取字符串
似水的流年
2018/01/14
6.7K0
-GET和POST请求添加请求参数和请求头【TBK使用】
我们平常浏览各个网站时,不免有时候就需要填写一些信息,比如注册时,登录时,这些信息一般都是通过GET请求或者POST(敏感信息一般使用POST,数据隐藏,相对来说更安全)请求提交到后台,经过后台的一系列处理,再返回给前台结果,前台进行处理。
凯哥Java
2019/06/28
6.5K0
[android] 请求码和结果码的作用
当一个界面中要要开启多个带有返回值的activity时,这个时候,就需要用到请求码和结果码了
唯一Chat
2019/09/10
5200
获取URL地址中的GET参数
/*-----------------实现1--------------------*/ function getPar(par){ //获取当前URL var local_url = document.location.href; //获取要取得的get参数位置 var get = local_url.indexOf(par +"="); if(get == -1){ return false; } //截取字符串
似水的流年
2019/12/11
6.4K0
获取URL地址中的GET参数
/*-----------------实现1--------------------*/ function getPar(par){ //获取当前URL var local_url = document.location.href; //获取要取得的get参数位置 var get = local_url.indexOf(par +"="); if(get == -1){ return false; } //截取字符串
似水的流年
2018/01/18
7.1K0
[javascript] js获取url中的get参数
调用数组的map函数 , map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
唯一Chat
2021/05/17
10.6K0
request中的方法_requests发送get请求
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/09/29
1.1K0
点击加载更多

相似问题

JS与.NET夏令行为的差异

20

PHP与Python代码的差异-数组、Foreach循环

12

PHP 5.2.0与PHP 5.3.3中的Foreach迭代器行为差异

30

与码头货柜的行为差异

12

C# - For与Foreach性能差异巨大

20
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文