记忆斐波那契的时间复杂度

2024-01-13

我最近遇到了这个 Haskell 记忆斐波那契实现:

fibonacci :: Int -> Integer
fibonacci = (map fib [0 ..] !!)
  where fib 0 = 0
        fib 1 = 1
        fib n = fibonacci (n - 1) + fibonacci (n - 2)

我想知道第一次生成第 n 个斐波那契数的时间复杂度。是因为 Haskell 中的列表查找而导致 O(n^2) 吗?如果是,那么有没有办法以某种方式使其成为 O(n),就像查找操作为 O(1) 的语言一样?


是因为 Haskell 中的列表查找而导致 O(n^2) 吗?

Yes.

如果是,那么有没有办法以某种方式使其成为 O(n),就像查找操作为 O(1) 的语言一样?

最简单的方法是使用惰性数组,它具有 O(1) 随机访问。这意味着,您必须指定数组大小,这样您就不再具有无限序列,但在其他语言中也有相同的限制。例如,您可以使用这样的方法Data.Vector:

import Data.Vector

fibsUpto100 :: Vector Integer
fibsUpto100 = generate 100 fib
    where fib 0 = 0
          fib 1 = 1
          fib n = fibsUpto100 ! (n-1) + fibsUpto100 ! (n-2)

由于惰性,在计算向量的元素之前不会计算任何内容,此时向量的所有先前元素(之前尚未计算过)也将被计算。一旦计算完毕,每个值都会存储在向量中,因此不会对任何值进行多次计算。

当然,如果有无限的数字列表就更好了。实现此目的的一种方法是将计算第 n 个斐波那契数的标准 O(n) 方法(使用跟踪当前和前一个元素的 while 循环)转换为递归 Haskell 函数,然后调整该函数以将每个元素存储在一个列表。

while 循环的基本翻译是:

fib 0 = 0
fib n = fibHelper n 0 1
  where
    fibHelper 0 _ current = current
    fibHelper n previous current =
        fibHelper (n-1) current (current + previous)

调整它以保留列表,我们得到:

fibs = 0 : genFibs 0 1
  where
    genFibs previous current =
        current : genFibs current (current + previous)

另一种更简洁的方法是使用自己的尾部来定义列表。也就是说,我们希望列表中的每个元素都是前一个元素+之前的元素,我们通过获取列表及其尾部,将它们添加在一起并将结果反馈到列表中来实现这一点。这导致以下定义:

fibs = 0 : 1 : zipWith (+) fibs (tail fibs)

这里 0 和 1 分别是第一个和第二个元素,然后剩余的元素在由zipWith (+) fibs (tail fibs)。该列表的第一个元素(即整个列表的第三个元素)将是fibs+ 第一个元素tail fibs, so 0 + 1 = 1,下一个元素是1 + 1 = 2等等。所以这个定义实际上产生了斐波那契数列。


1 尽管对于不太习惯在头脑中打递归结的人来说可能不太容易理解。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

记忆斐波那契的时间复杂度 的相关文章

  • 文件修改时间检查的成本

    对于Linux下包含少量字节的文件 我只需要处理自上次处理以来发生更改的时间 我通过调用 PHP 检查文件是否被更改clearstatcache filemtime 定期 由于整个文件总是很小 因此删除对 filemtime 的调用并通过将
  • 举例解释bpe(字节对编码)?

    有人可以帮忙解释一下背后的基本概念吗BPE模型 除了这张纸 https arxiv org abs 1508 07909 目前还没有那么多解释 到目前为止我所知道的是 它通过将罕见和未知的单词编码为子词单元序列来实现开放词汇表上的 NMT
  • * 到底有多慢?

    大家都表示 选择器非常慢 但它到底有多慢呢 我总是试图避免它 但有时它非常有用 例如 h1 margin top 1em 简单来说 通用选择器 速度只与页面上的元素一样慢 Since 从右到左匹配浏览器获取每个元素并将其与所有候选规则进行匹
  • 在 Haskell 中合并两个列表

    无法弄清楚如何合并两个列表通过以下方式在哈斯克尔 INPUT 1 2 3 4 5 11 12 13 14 OUTPUT 1 11 2 12 3 13 4 14 5 我想提出一个更懒的合并版本 merge ys ys merge x xs y
  • 为 PostgreSQL 查询选择正确的索引

    简化表 CREATE TABLE products product no integer PRIMARY KEY sales integer status varchar 16 category varchar 16 CREATE INDE
  • Data.Sequence 中的 inits 和 tails 如何工作?

    Louis Wasserman 编写了当前的实现inits and tails in Data Sequence 他表示它们非常高效 事实上 只要查看代码 我就可以看到 无论它们在做什么 它们都是以干净 自上而下的方式进行的 这往往会给惰性
  • 为什么n++执行速度比n=n+1快?

    在C语言中 为什么n 执行速度快于n n 1 int n n int n n n 1 我们的老师在今天的课堂上问了这个问题 这不是家庭作业 如果您正在开发一个 石器时代 编译器 的情况下 石器时代 n比n 比n n 1 机器通常有incre
  • 检查对以下内容的理解:“变量”与“变量” “价值”、“功能”与“抽象”

    这个问题是后续问题this one https stackoverflow com questions 25327705 is function a sort of variable 25329157 25329157在学习 Haskell
  • 加快网络抓取速度

    我正在使用一个非常简单的网络抓取工具抓取 23770 个网页scrapy 我对 scrapy 甚至 python 都很陌生 但设法编写了一个可以完成这项工作的蜘蛛 然而 它确实很慢 爬行 23770 个页面大约需要 28 小时 我看过scr
  • 二维滑动窗口最小值/最大值

    假设我们得到一个大小为 NxN 的像素整数矩阵和一个整数 k 窗口大小 我们需要使用滑动窗口找到矩阵中的所有局部最大值 或最小值 这意味着 如果某个像素与其周围窗口中的所有像素相比具有最小 最大 值 则应将其标记为最小 最大 有一种著名的滑
  • 为什么列表理解在数组相乘方面比 numpy 快得多?

    最近我回答了THIS https stackoverflow com questions 31596979 multiplication between 2 lists 31597029 31597029想要两个列表相乘的问题 一些用户建议
  • Haskell:不在范围内:数据构造函数

    今天开始在学校学习 haskell 我遇到了函数问题 我不明白为什么它不在范围内 代码如下 ff Char gt Char gt Char ff A B x 0 y 1 x lt A y lt B x 1 y 0 和错误 md31 hs 2
  • 如何提高包含大量小图像的 UCollectionView 的性能?

    在我的 iOS 应用程序中我有UICollectionView显示大约 1200 个小 35x35 点 图像 图像存储在应用程序包中 我正确地重用了UICollectionViewCell但仍然存在性能问题 具体取决于我处理图像加载的方式
  • 针对约 225 万行的单表选择查询的优化技术?

    我有一个在 InnoDB 引擎上运行的 MySQL 表 名为squares大约有 2 250 000 行 表结构如下 squares square id int 7 unsigned NOT NULL ref coord lat doubl
  • 正则表达式库基准

    我最近一直想知道正则表达式实现的性能 并且很难想出很多有用的信息 它很容易对浏览器 javascript 正则表达式性能进行基准测试 网上有很多工具 Chrome 和 Opera 中的 javascript 正则表达式实现几乎摧毁了所有其他
  • 类型级别集结合律的证明

    我试图证明类型级函数Union https hackage haskell org package type level sets 0 8 5 0 docs Data Type Set html t Union是关联的 但我不确定应该如何完
  • Javascript 播放声音性能重吗?

    我正在用 Javascript 制作一个简单的游戏 当一个物体与墙壁碰撞时 它会发出 砰 的声音 声音的响度取决于物体的速度 速度越高 gt 声音越大 播放功能 playSound function id vol ID of the sou
  • 将名称字符串编码为唯一的数字

    我有一大堆名字 数以百万计 他们每个人都有一个名字 一个可选的中间名和一个姓氏 我需要将这些名称编码为唯一代表这些名称的数字 编码应该是一对一的 即一个名称只能与一个数字相关联 一个数字只能与一个名称相关联 对此进行编码的明智方法是什么 我
  • 列出所有 k 元组,其条目总和为 n,忽略旋转

    有没有一种有效的算法来查找所有序列k总和为的非负整数n 同时避免旋转 如果可能的话 完全避免 顺序很重要 但对于我正在解决的问题来说 轮换是多余的 例如 与k 3 和n 3 我想要得到一个如下所示的列表 3 0 0 2 1 0 2 0 1
  • 关于“没有绑定的类型签名”的错误

    我在 Haskell 中遇到 ASCII 问题 fromEnum Char gt Int toEnum Int gt Char offset Int offset fromEnum A fromEnum a toUpper Char gt

随机推荐

  • mysql 根据原始 sql 创建过程的问题

    我正在 Symfony2 中处理一个应用程序项目 通过注册 每个客户端都会创建一个数据库 模式是在客户端登录时由验证服务创建的 该应用程序需要一些数据才能工作 到目前为止 我使用了 ORM 夹具 由于多种原因 我现在需要从夹具加载转向更接近
  • 不区分大小写的正则表达式 - VBA

    Background 刚才我正在回答一个问题 正在玩玩RegEx within VBA 目标是创建字符串中存在的名称列表 RegEx是首选解决方案 因为我们想防止VBA绊倒看起来相似的标点符号和子字符串 例如 Jack or Jacky S
  • 获取另一个 jar 中一个 jar 的文件系统

    这就是我想做的 FileSystem fs1 FileSystems newFileSystem Paths get f1 jar null FileSystem fs2 FileSystems newFileSystem fs1 getP
  • 获取 iframe 标题并在 html 中回显 [重复]

    这个问题在这里已经有答案了 我从地址栏加载我的 iframe src 如下所示 http site com demo php go http google com http site com demo php go http google
  • C++ 父类调用子虚函数

    我想要一个纯虚拟父类来调用函数的子实现 如下所示 class parent public void Read read stuff virtual void Process 0 parent Read Process class child
  • 在单元测试中模拟 python 类并验证实例

    我正在尝试对 SFTP 帮助程序类进行单元测试 该类对 pysftp 模块进行一些调用 我想模拟来自 pysftp 的实际网络调用 这样就不会产生副作用 并且只需确保该类使用正确的参数正确调用底层 SFTP 方法即可 这是到目前为止我的代码
  • 如何在 ngRepeat 数组之间推送 AngularJS 中的对象

    所以我是 AngularJS 的新手 我正在尝试构建一个非常简单的列表应用程序 我可以在其中创建一个 ng repeat 项目列表 然后将选定的项目推送到另一个 ng repeat 列表中 虽然我的问题看起来很简单 但我还没有找到合适的解决
  • 在 JQGrid 中显示 Twitter Bootstrap 下拉菜单

    我使用自定义单元格格式化程序向每个 JQGrid 行添加了 twitter bootstrap 下拉菜单 当我单击菜单时 它不完全可见 我应该应用什么样式来在 JQGrid 行的最顶部显示下拉菜单 HTML td title Actions
  • 如何将数据从AppDelegate传递到ViewController?

    我正在使用 Safari 浏览网页 单击此页面上的按钮后 我的 iPad 将启动我的应用程序 所以我实现了该方法 BOOL application UIApplication application handleOpenURL NSURL
  • JPA 2.0 子选择/子查询按条件 api 的 order by 子句

    我想使用 JPA 2 0 criteria api 来构建带有子选择的 order by 子句 我知道你可以用普通的 SQL 来做到这一点 但是它可以用标准 api 来映射吗 有人可以给出代码示例吗 Example Order name a
  • 在 C++ 中可以锁定变量以防止对其进行更改吗?

    我正在使用一个成员变量 并且在程序的某个时刻我想更改它 但我更喜欢在其他地方 锁定它 以防止意外更改 代码解释 class myClass int x This should be prevented to being changed mo
  • 如果 JavaScript 构造函数失败,应该返回什么?

    如果我有一个无法实例化的 javascript 类 构造函数应该返回我可以测试的内容 构造函数总是返回一个对象 因此如果构造函数失败 我不能返回 null function SomeClass id if typeof id number
  • 使用 D3.js 沿连续路径进行插值

    我正在改编迈克 博斯托克的作品沿路径点插值 http bl ocks org mbostock 1705868模型接受数组n单独的路径并沿着每个路径进行插值连续地 对于 D3 来说 下面的代码相对较新 据我所知 它是为两条路径运行点插值同时
  • 在 Google App Engine 日志中查看 POST 请求的参数

    我有一个通过 Google App Engine 运行的服务器 我正在通过控制台查看服务器的请求日志 它们位于Google Cloud Platform gt Stackdriver Logging gt Logs 我想查看 POST 请求
  • 在 Python 中模拟远程主机

    我正在使用 paramiko 编写一些函数来执行命令并在远程主机上创建文件 我想为它们编写一些单元测试 但我不知道实现此目的最简单的方法是什么 这是我设想的代码大纲示例 import os import paramiko import py
  • 无法找到或加载主类org.apache.zookeeper.server.quorum.QuorumPeerMain [重复]

    这个问题在这里已经有答案了 我正在运行 apache kafka 的教程 在 apache kafka 网站上 并且必须使用帮助教程 http janschulte wordpress com 2013 10 13 apache kafka
  • Ruby on Rails - 根据查询在数据库中搜索

    我有一个简单的表单 我在其中设置了一个我想要浏览的查询 例如松下维埃拉 这是我在数据库中搜索术语的方式 Product where name ilike params q order price 查询看起来像 松下维埃拉 但我需要这样搜索查
  • 需要适用于 Iphone、Android、Windows/XP 的兼容 AES 代码加密/解密

    我需要能够从 Windows 向各种手机发送安全信息 我在 iPhone 和 Android 开发方面都是新手 但需要为每个环境创建一个易于使用的应用程序 与收到的短信交互也很好 我想获取适用于 iPhone Android 和 Windo
  • 如何在android活动中使用gradle.properties中的属性?

    如何在android活动中使用gradle properties中的属性 每当我构建代码时 它都会抛出错误 是否有可以在活动内部访问属性的特定方式 在 gradle properties 中 SIMPLE STRING ABC 在 buil
  • 记忆斐波那契的时间复杂度

    我最近遇到了这个 Haskell 记忆斐波那契实现 fibonacci Int gt Integer fibonacci map fib 0 where fib 0 0 fib 1 1 fib n fibonacci n 1 fibonac