在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, .... ]
所以斐波那契数列的无限列表可以通过将元素1
和1
加到无限列表斐波纳契数字后面的结果来计算,斐波那契数列的无限列表使用+
运算符的无限列表。
现在,要得到第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 n
和fib (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