Fibonacci Seq。奇怪的输出形式(Haskell)

时间:2013-05-26 17:47:24

标签: haskell sequence fibonacci

当我在数字输入中发现一些“奇怪的”形式时,我正在观察Haskell中我的Fibobacci序列实现的结果。

首先,这是我提出的Haskell代码:

fib :: Integer -> [Integer]
fib 0 = [0]
fib 1 = [0, 1]
fib a = (fib' 0 1 [0,1] 1 a)

fib' :: Integer -> Integer -> [Integer] -> Integer -> Integer -> [Integer]
fib' n1 n2 l cont n 
        | cont == n = l
        | otherwise = (fib' n2 n3 (l++[n3]) (cont+1) n)
             where n3 = n2 + n1

对于像fib 10这样的东西,输出将是:[0,1,1,2,3,5,8,13,21,34,55] 然后我想尝试像fib 1000这样的东西,而数字非常大而且所有......我看到的是由“,”形成的一些奇怪的elipses,从列表中的每个Integer之间打印出来,例如:

example1

所以我最大化了输出窗口的大小,看看这个奇怪的模式是否仍会重复,答案是肯定的:

example2

我的问题是:

有人知道为什么在列表中的整数之间出现“,”这个模式? 它不应该更随意,更像是没有钱包吗?

2 个答案:

答案 0 :(得分:21)

n 的斐波纳契数grow as an exponential function

十进制数的长度本质上是它的对数基数10.因此,斐波那契的长度像 n 的线性函数一样增长,因为对数和指数相互抵消。

因此,如果您将它们打印在一列中,您会看到一条直线。但是你要一个接一个地打印它们,所以这些位置会累积起来。如果您正在获取线性序列的累积和,则会得到二次序列。

在本地,每一行包含大约相同数量的Fibonacci数字,我们称之为 k 。这意味着两件事:

  1. 行号与 n 线性变化。
  2. 要计算逗号的实际位置(相对于窗口的左边缘),我们需要将累积“绝对位置”的剩余部分取为行长度的模数。这相当于(平均而言)每 n 的每个增量减去 1 / k 。此调整是线性的,不会改变位置的二次行为。
  3. 所以你所看到的是抛物线 - 二次函数图。

答案 1 :(得分:3)

当你想到它时,没有什么奇怪的。相邻的斐波纳契数具有相似的长度,并且长度随着序列而增加。假设你有一个30个字符的屏幕大小,而你当前的F(n)有29个数字,那么对于接下来的几个数字,长度可以是:

29, 29, 29, 30, 30, 30, 31, 31, 31

哪个给你左边 - >稳定 - >正确的运动。