斐波那契數列的四種實現

孔乙己本身知道不能和他們談天,便只好向 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

我曾經也把手寫斐波那契做爲面試題之一。

1. 遞歸

在編程教程中提到斐波那契數列,一般都是用來說解遞歸函數。當一個關於 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=' ')

2. 循環

但斐波那契並不是必定要用遞歸實現。事實上,全部的遞歸均可以用循環來實現。

def fib_2(n):
    a, b = 0, 1
    for i in range(n):
        print(b, end=' ')
        a, b = b, a + b

fib_2(20)

3. 生成器

用生成器的思路本質來講和上面的循環是同樣的,只是實現的時候用了 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=' ')

4. 矩陣相乘

此方法的原理是利用二階矩陣的相乘:

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的編程教室

相關文章
相關標籤/搜索