此處的C++斐波那契數列是如何實現的?
這裡的x,y,a,b,t分別代表什麼?是如何implement的?不理解啊嗚~(&>_
這是Fibonacci的二分演算法,時間複雜度為
鑒於初學者,我盡量詳細解答(這個代碼寫得也是夠晦澀難懂的,一定是喪心病狂的ACM選手寫出來的):Fibonacci數列中有恆等式:(式1)
(式2) (式3)(式1)和(式2)可由(式3)帶入m=n推得.一個數的二進位表示為:
為n的二進位數的數碼為0或1.好來看代碼,我來一行行解釋這是怎麼回事:double Fibonacci(int n){
double x = 1.0, y = 1.0, a = 0, b = 1.0,t;
while (n&>0)
{
if (n 1){
t = a*x + b*y;
a = x*(b - a) + a*y;
b = t;
}
t = 2 * x*y - x*x;
y = x*x + y*y;
x = t;
n &>&>= 1;
}
return a;
}
先看循環體:
while (n&>0)
{
if (n 1){
//...
}
//...
n &>&>= 1;
}
這個循環表示遍歷n的每一位,其中if若表示n的最後一位是否為1.最後的n &>&>= 1;表示每次將n所有位右移一位,則相當於循環中遍歷n的每一個數位.
第一行:
double x = 1.0, y = 1.0, a = 0, b = 1.0,t;
初始化,幾個變數分別儲存的值為:
x:y:a:b:t: 迭代中的臨時變數其中i表示循環過程中當前對應n的第i位,為n的前i位表示的數值初始時:x==1; y==1; =0; a==0; b==1;當循環結束後有n=0,則a=,為Fibonacci數列第n項,返回a
return a;
然後看循環體中最關鍵的部分:
先看這裡,a:和b:的部分:if (n 1){
t = a*x + b*y;
a = x*(b - a) + a*y;
b = t;
}
如果n的第i位為1則:
由:得到:對應:t = a*x + b*y;
//...
b = t;
a = x*(b - a) + a*y;
然後是這裡:
t = 2 * x*y - x*x;
y = x*x + y*y;
x = t;
由
代入和計算得出:和即是x,y/*
喵了個咪的,一開始看到和 @Milo Yip 一樣也以為是矩陣乘法展開,時間複雜度也為,答完了發現不是,算了還是不刪了,還是留著順便給題主參考一下:Fibonacci的遞推式為:用矩陣的方式表示可得:即:
矩陣乘滿足結合律,可得通項公式為:最後使用二分法計算: n為偶數: n為奇數:結果為*//*如果還有什麼地方講得不清楚可以手動模擬一下也歡迎來問~
最後吐槽一下用double...*/這種矩陣技巧複雜度是logn,他主要是為了解決你用通項公式時出現黃金分割數求冪精度丟失。通項可由矩陣對角化得出。所以通過矩陣有時可以容易保存精度。具體在mit的演算法導論公開課分治法也有說到。公開課視頻地址http://v.163.com/movie/2010/12/8/U/M6UTT5U0I_M6V2T998U.html?
逆向工程好難,推了好久,終於看懂了。。。
可以認為它在用二分的方法來求Fibnacci數。這裡的Fibnacci數的定義為F[0] = 0, F[1] = 1, F[2] = 1, F[3] = 2, ...由Fibnacci數的性質設,則設得
可以認為一直維護的是部分積,一直維護的是吧。
希望我說明白了。。。
這是計算斐波那契數列的一種快速演算法,時間複雜度是log(n)如果你不理解起背後的數學原理,看不懂是很正常的。這個做法我之前看到時出現在Knuth的某本書中,反正不是TAOCP就是具體數學。不過也沒怎麼記,因為有更易於理解的矩陣解法。如果你是初學者(我看你在紙上寫代碼....),請不要執著於這個問題
Structure and Interpretation
of Computer Programs Ex1.19
來看看。
一樣的筆記,我匿了
剛剛上完課,這道是家庭作業,你是我同學嗎,我還是匿了吧。
推薦閱讀:
※muduo::StringPiece?
※嵌入式這行業是不是不行了?
※使用sprintf時溢出怎麼會影響到變數的值?
※小弟做c++伺服器差不多一年了,用ace框架的,還沒什麼信心,還很菜,請教各位大神如何提升進階啊?
※計算機專業C++應該怎麼教?
TAG:斐波那契LeonardoFibonacci | C |