黑馬程式設計師____比較不同方法求Fibonacci數
----------------------android培訓、java培訓、期待與您交流! ----------------------
一、實驗環境
作業系統:Windows 7 Ultimate 64bit SP1
處理器:Intel Core i7-2630QM CPU @ 2.00GHz
記憶體:8GB (DDR3 1333MHz)
程式語言Visual C# 4.0
編譯環境Visual Studio 2010 + Release + Optimize Code
二、 實驗方法
由Fibonacci數列的定義,我們有如下的遞推式:Fn=Fn-1 + Fn-1
通過定義來計算數列的Fn需要的時間複雜度為O(n),空間複雜度O(1)。
而Fibonacci數列還能通過如下的矩陣方法計算:
即要計算數列的Fn+1只需要計算A^n,而A^n能夠通過分治法在時間複雜度O(lgn)的情況下計算出來。
實驗中需要注意的地方是,如果使用無符號長整數資料型別來計算Fn,那麼從第48項開始資料就會溢位,
即使使用無符號長整數資料型別,從第94項開始資料也會溢位。因此如果只是使用基本資料型別,
那麼後面的項將無法正確計算。所以實驗還需要實現一個能夠處理大整數的資料型別,在實驗中我們
使用了一個無符號長整數動態陣列來實現一個基數為10^8的大整數類,陣列下標為0的元素則對應了
“個”位,以此類推。這個大整數類實現了加法和乘法,時間複雜度分別為O(n),O(n^2),而乘法還能改進
的地方,比如使用分治法能夠將時間複雜度改進到O(n^ log2^3),而使快速傅立葉變換則恩給你改進到
O(nlgn)
三、實驗結果
圖1 實驗資料
雖然前面提及過用遞推法和矩陣法求Fibonacci數列Fn的時間複雜度分別為O(n),O(lgn),但是從圖表
中能夠看出兩種方法執行時間的曲線並不是像分析的那樣。這是因為分析的時候是假設數的加法或是
乘法都是能夠在O(1)時間複雜度內完成的,然後實際的情況是我們必須使用大整數類才能保證計算的正確,
而使用大整數類進行運算的時候,加法和乘法都將不能夠在O(1)時間複雜度內完成的,在本實驗中實現的
大整數類加法和乘法的時間複雜度分別為O(n),O(n^2),與數的長度有關。因此兩種方法執行時間的曲線
也就不能像原先分析的那樣,而是呈現圖表中這樣的曲線。
---------------------- android培訓、java培訓、期待與您交流! ----------------------