【发布时间】:2014-12-28 23:25:56
【问题描述】:
作为学习 Haskell 的一部分,我编写了以下斐波那契游戏程序:
fibonacci 0 = [0]
fibonacci 1 = [0,1]
fibonacci n = let
foo'1 = last (fibonacci (n-1))
foo'2 = last (fibonacci (n-2))
in reverse((foo'1 + foo'2):reverse (fibonacci (n-1)))
程序有效:
ghci>fibonacci 6
[0,1,1,2,3,5,8]
但是,性能随着 n 呈指数下降。如果我给它一个 30 的参数,它需要大约一分钟的时间来运行,而不是在 6 时立即运行。看起来懒惰的执行让我很着急,斐波那契为最终列表中的每个元素运行一次。
我是在做傻事还是错过了什么?
(我已经摆脱了可能会这样做的 ++ 想法)
【问题讨论】:
-
这看起来像是教科书的例子,说明memoization 变得有用。
-
当 一个 就足够时,您正在进行 三个 递归调用。我会写
reverseFib以反向返回斐波那契数,因为这样更容易。一旦定义好,您就可以定义fibonacci = reverse . reverseFib,以便在最后只反转一次列表。 (当然,Haskell 中还有其他众所周知的方法,例如在列表而不是函数上递归......但暂时忘记这些) -
我认为记忆是这里的关键,因为我每次想引用其中一个成员时都会重新计算列表。我会检查出来的! (哈!我看到递归示例使用了斐波那契数列)。
标签: haskell fibonacci memoization