? ? ? 各位看官們好,當我寫了上一篇博客楊輝三角后,有一些看官叫我講一下斐波那契數列。對于這個大家應該是有了解的。最簡單的規律就是f(n)=f(n-2)+f(n-1)。就是當前是前兩項之和,然后下標1和0都是1.從第三項開始計算的。那么我們知道規律,那么我們就直接來講講如何實現和實現方法有哪些吧。
遞歸
? ? ? ? 我想大家學習C語言到現在應該看到斐波那契數列應該想到的是遞歸吧。我想遞歸大家應該還知道它的核心思想吧,就是每遞歸一次,那么這個問題就要越靠近我們想要的答案一次,一直遞歸到想要答案就返回。好,那么我們現在想一想怎么搞。那么我們知道我們有特殊情況就是,如果我輸入1和2的話,那么我們得到的值是1.那么我們這個就可以直接寫出來哇。好當我們寫出了特殊情況后,我們來思考正常情況。那么我們也知道我們規律就是前兩項之和。那么我們就直接寫啊,是不是。大家思考一下:
int xixi(int a)
{if (a == 1 || a == 2){return 1;}else{return xixi(a - 1) + xixi(a - 2);}
}
int main()
{int a = 0;printf("請輸入要多少位的斐波那契數\n");scanf("%d", &a);printf("%d ", xixi(a));return 0;
}
? ? ? ? 我們只要不是特殊情況的話,我們只需要在遞歸的時候將前兩項傳來,直到設定的值,那么我們就可以得到結果了。大家思考一次,是吧。代碼很簡單,但是有一個問題就是。遞歸的內存占用太多了。很有可能造成棧溢出。也許大家輸入前面的數字編譯器還是很快的輸出的。但是當我們輸入較大值如100這類的我們就可以明顯的感覺速度很慢了。所以遞歸大家可以知道這個方法但是使用起來限制還是很大了。大家知道有這個辦法就可以了。
for循環
? ? ? okok,當我們寫了遞歸后,我們遞歸其實還是有點難度的,畢竟我們還是需要思考一下,怎么實現的吧。但是我們要是用for循環的,我們從最開始學習C語言的時候我們就知道有個for循環。那么最基礎的知識其實是很有作用的,那么我們來思考一下for循環如何來實現我們的斐波那契數吧。但其實for循環也是比較簡單的,畢竟大家思考一下。我們最基本的規律就是前兩項之和f3,那么我們就創建三個變量吧。一個作為最后的相加項我們最后返回的。然后另外兩個就一個作為前一項f1一個作為前兩項f2。那么這個如何交換值值嘞。首先我們就最開始的時候考慮特殊情況。1和2的時候那么我們就直接從2開始吧,如果我輸入的值是1或者2的話,for本來就等于2了,不執行,然后直接返回f3。那么我們可以確定了f3的初始值為1吧。并且我們現在把特殊情況也處理了。那我們正常的話f3=f1+f2。然后f2=f3。這個是為什么嘞,因為我們大家算f3,是不是就是我們的前一個f3加一個f2但我不能直接寫f3的前一項啊。所以f2就成為上一個f3吧。那f2成為上一個f3那。f1自然而然的變成了上一個的f2了吧。這樣大家是不是就通透了呀。我們將f1,2,3全部設為1.然后for循環從2開始那么就排除了特殊情況。然后最開始就將f3更新,然后f2和f1相繼跟新這樣如果下次沒有更新的話,我們就可以直接確定了返回值f3了。
int xixi(int a)
{int f3 = 1;int f2 = 1;int f1 = 1;for (int y = 2; y < a; y++){f3 = f1 + f2;f1 = f2;f2 = f3;}return f3;
}
int main()
{int a = 0;printf("請輸入要多少位的斐波那契數\n");scanf("%d", &a);printf("%d", xixi(a));return 0;
}
? ? ? ? 大家需要注意一下啊。就是f1與f2更新的順序不要亂哦。不然的話f1也變成上一個f3了。然后就太多的麻煩了。
數組
? ? ? ? OK呀,其實講了上面的兩個方法就差不多了的,但是我還想到了一個方法,就是我們使用數組來實現這個。那大家先想一想數組如何實現這個了。但其實啊。也很簡單與我們的for循環是差不多的。我們上一個for循環是需要實時更新的,但我們數組其實就是很簡單的。我們創建一個較大的數組。然后沒循環一次,那么就往數組里寫入新的值,然后循環到設定值結束,那么就返回這個數組下標的的元素就可以了。那么簡單的思路那我們就直接開始搞吧。
int xixi(int a)
{int i = 0;int arr[100] = {0, 1,1};for (i = 2; i <= a; i++)//從第一項開始{arr[i] = arr[i - 1] + arr[i - 2];}return arr[a];}
int main()
{int a = 0;printf("請輸入要多少位的斐波那契數\n");scanf("%d", &a);printf("%d", xixi(a));return 0;
}
? ? ? ? 大家看看上面咦。為什么我們創建數組的時候開始要給0,1,1的值啊。其實也很簡單就是我們數組下標啊。我們原本計算的都是從1開始的,但是我們數組是下標如果不設置得話,那么下標0為1,設置的值就會大很多,當然是越向后值就比正確值大很多。大家可以下來嘗試一下。
? ? ? 好了,那么我們上面三種方法就差不多了,遞歸方法雖然有,但是可以處理小部分遞歸次數較小的,如果太大了。那么就是會很慢甚至報錯。建議少用用for循環的方法也可以。好了。以上就是本篇博客的內容了。如果還有補充的話,希望大家可以評論區留言。