在Haskell中生成斐波那契数列?

在Haskell中,如何根据第n个斐波纳契数等于第(n-2)个斐波那契数加上第(n-1)个斐波那契数的性质生成斐波纳契数?

我见过这个:

fibs :: [Integer]
fibs = 1 : 1 : zipWith (+) fibs (tail fibs)

我真的不明白,或者它如何产生一个无限列表,而不是一个包含3个元素的列表。

我如何编写可以通过计算实际定义来工作的haskell代码,而不是通过对列表函数执行一些非常奇怪的操作?


这是一个简单的函数,可以计算第n个斐波纳契数:

fib :: Integer -> Integer
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

你问题中的功能是这样的:

假设你已经有了一个斐波那契数列的无限列表:

   [ 1, 1, 2, 3, 5,  8, 13, .... ]

这个清单的tail

   [ 1, 2, 3, 5, 8, 13, 21, .... ]

zipWith使用给定的运算符将元素按元素组合在一起:

   [ 1, 1, 2, 3,  5,  8, 13, .... ]
+  [ 1, 2, 3, 5,  8, 13, 21, .... ]
=  [ 2, 3, 5, 8, 13, 21, 34, .... ]

所以斐波那契数列的无限列表可以通过将元素11加到无限列表斐波纳契数字后面的结果来计算,斐波那契数列的无限列表使用+运算符的无限列表。

现在,要得到第n个斐波那契数,只需得到斐波纳契数的无限列表的第n个元素:

fib n = fibs !! n

Haskell的美妙之处在于它不计算Fibonacci数列表中的任何元素,直到它需要为止。

我是否让你的头部爆炸? :)


扩展dtb的答案:

“简单”解决方案之间有一个重要的区别:

fib 0 = 1
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

你指定的那个:

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

简单的解决方案需要O(1.618NN)时间来计算第N个元素,而您指定的那个需要O(N2)。 这是因为你指定的那个考虑到计算fib nfib (n-1) (计算它所需的)共享fib (n-2)的依赖性,并且它可以被计算一次以便保存时间。 O(N2)用于N个数字的O(N)数字。


按照定义,斐波那契数列的每一项都是前两项的和。 把这个定义放到懒惰的哈斯克尔给你这个!

fibo a b = a:fibo b (a+b)

现在只需要从0,1开始从fibo中取出n个项目

take 10 (fibo 0 1)
链接地址: http://www.djcxy.com/p/39909.html

上一篇: Generating Fibonacci numbers in Haskell?

下一篇: How to write the Fibonacci Sequence?