孔乙己本身知道不能和他们谈天,便只好向 Intern 说话。有一回对我说道,“你写过代码么?”我略略点一点头。他说,“写过代码,……我便考你一考。斐波那契数列的输出,怎样实现?”我想,讨饭同样的人,也配考我么?便回过脸去,再也不理会。孔乙己等了许久,很恳切的说道,“不能写罢?……我教给你,记着!这些代码应该记着。未来作 Leader 的时候,开发项目要用。”我暗想我和 Leader 的等级还很远呢,并且咱们 Leader 也从不在项目里写斐波那契;又可笑,又不耐烦,懒懒的答他道,“谁要你教,不是递归么?”孔乙己显出极高兴的样子,将两个指头的长指甲敲着键盘,点头说,“对呀对呀!……斐波那契有四样写法,你知道么?”我愈不耐烦了,努着嘴走远。孔乙己刚在命令行打开 Vim,想在里面写代码,见我绝不热心,便又叹一口气,显出极可惜的样子。
(改编自 鲁迅《孔乙己》)
在家闲着也是闲着,不如咱们来看看,如何写一个输出斐波那契数列的代码吧。面试
先说下,什么是 斐波那契数列 ?编程
斐波那契(Fibonacci)数列,又称黄金分割数列,因数学家列昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:函数
一、一、二、三、五、八、1三、2一、34……spa
在数学上,斐波那契数列以以下被以递推的方法定义:命令行
F(1) = 1code
F(2) = 1blog
F(n) = F(n - 1) + F(n - 2) (n ≥ 3,n ∈ N*)教程
简单来说就是:数列中 某一项的值,等于它的前一项加上前前一项的和 。递归
在现代物理、准晶体结构、化学等领域,斐波纳契数列都有直接的应用,为此,美国数学会从 1963 年起出版了以《斐波纳契数列季刊》为名的一份数学杂志,用于专门刊载这方面的研究成果。(摘自 百度百科)ci
我曾经也把手写斐波那契做为面试题之一。
在编程教程中提到斐波那契数列,一般都是用来说解递归函数。当一个关于 N 的问题能够转换为关于 N - k 的一样问题时,它就能够尝试用递归的思路来解决。
def fib_1(n): if n <= 1: return 1 return fib_1(n-1) + fib_1(n-2) for i in range(20): print(fib_1(i), end=' ')
但斐波那契并不是必定要用递归实现。事实上,全部的递归均可以用循环来实现。
def fib_2(n): a, b = 0, 1 for i in range(n): print(b, end=' ') a, b = b, a + b fib_2(20)
用生成器的思路本质来讲和上面的循环是同样的,只是实现的时候用了 yield 。
def fib_3(n): a, b = 0, 1 while n > 0: yield b a, b = b, a + b n -= 1 for i in fib_3(20): print(i, end=' ')
此方法的原理是利用二阶矩阵的相乘:
import numpy as np def fib_4(n): for i in range(n): res = pow(np.matrix([[1, 1], [1, 0]], dtype='int64'), i) * np.matrix([[1], [0]]) print(int(res[0][0]), end=' ') fib_4(20)
上述 4 种方法的输出结果都是:
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
斐波那契数列的实现方法并不只这 4 种。若是你有其余的实现,欢迎在留言中补充。
------
一块儿学,走得远!
欢迎搜索: Crossin的编程教室