
ちょうど学校でフィボナッチ数列の話題になったので、思いつきで作ってみました。
そこで、配列を使ったものと再帰呼び出しを使ったものを作りました。
//再帰呼び出し
unsigned long Fibonacci(int n){
if(n==1){ return 1;}//初項
else if(n==2){ return 1;}//第2項
return Fibonacci(n-1) + Fibonacci(n-2);
}
//配列
unsigned long Fibonacci(int n){
unsigned long long f[101];
int i;
f[1] = 1;
f[2] = 1;
for( i=3; i<=n; i++){
f[i] = f[i-1] + f[i-2];
}
return f[n];
}
この二つを比較すると明らかに配列の方が早いです。
ということは再帰呼び出しはあまり使わない方がよいってことですよね?
この場合は配列も似たような感じで見ることができますし。
それとも自分の再帰の書き方が悪いのでしょうか。
No.1ベストアンサー
- 回答日時:
>この二つを比較すると明らかに配列の方が早いです。
>ということは再帰呼び出しはあまり使わない方がよいってことですよね?
いいえ、違います。
求める項nが「ある程度以下」なら配列で処理出来ますが、もし、項nが大きく、それだけの配列を確保出来ない場合、遅いと判ってても再帰を使わざるを得ない場合があります。
>それとも自分の再帰の書き方が悪いのでしょうか。
「再帰関数が何回呼び出されるか?」を考えれば「再帰が如何に遅いか」が判ります。
項nの呼び出し回数は「項nのフィボナッチ数×2-1」です。n=10のフィボナッチ数は55ですから、55×2-1=109で、109回も呼び出されます。
最後に、再帰呼出も配列も使わない(nに制限がなく、スピードも速い)関数を書いておきます。参考にして下さい。
unsigned long Fibonacci(int n)
{
int i;
unsigned long a,b,c;
for (i=1,a=0,b=1;i<n;i++) {
c=a+b;
a=b;
b=c;
}
return b;
}
>求める項nが「ある程度以下」なら配列で処理出来ますが
一応nがそんなに大きくならなくてもn項目の値がとても大きかったので、配列でもいいか、と思ってやってみました。
でも、配列も再帰も使わなくてもできるんですね。
とても参考になりました。
ありがとうございました。
No.3
- 回答日時:
高速化についてはいろいろと議論があると思いますが。
「この二つを比較すると明らかに配列の方が早いです。
ということは再帰呼び出しはあまり使わない方がよいってことですよね?
この場合は配列も似たような感じで見ることができますし。
それとも自分の再帰の書き方が悪いのでしょうか。」
世の中、プログラムは速く動く事も重要ですが、「キレイに書く/他人が読み易く書く」という事も重要です。
再帰で書くと、フィボナッチの定義により近いと思いませんか?まあ、配列を使わない程度しか違いませんが。
大きなプログラムを、あるいはあなたがオープンソースを書いたとして、他人があなたの書いたプログラムを見て、何をしているのか理解しようとすることがあるとしましょう。この時、プログラムにコメントを入れる事も手助けになりますが、プログラムだけでも「キレイに」(要は他人から見られることを意識する、という意味)書いてあれば、理解の助けになると思いませんか?
職業でプログラムを書いていると、多くの場合、正しく動くことが一番重要で、速さはその次になったりします。多分、フィボナッチの授業は再帰呼び出しが数学的な再帰によくマッチして「キレイ」だ、という事を理解するのが目的だったのではないでしょうか。
P.S.
細かいようですが、C プログラマならば f[0] から始めて欲しかった.....
一応f[1]から始めたのは、なるべく数列に近づけようと思ったからです。
自分なりに見やすいかな、と思い、f[1]からにしました。
ちなみにフィボナッチの話は仲の良い数学の先生と「美しい!」ということで盛り上がったので・・・。
Cは独学です。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- その他(プログラミング・Web制作) 十進BASICでの再帰についての質問です。 2 2022/11/18 09:17
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# 変数のスコープ 5 2023/05/27 17:50
- C言語・C++・C# 10人分の生徒の英語の点数{32,34,41,38,40,26,14,46,42,50} と数学の点 2 2022/05/26 21:31
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語 配列の長さの上限
-
【C言語】配列の中に配列を入れ...
-
C# Listを使わずに2次元配列の...
-
先頭アドレスとは何ですか?
-
mallocの確保要素数の限界は?
-
配列を使わずに、変数名を動的...
-
C言語初心者 構造体 課題について
-
複数のボタンを配列で扱う方法...
-
C言語初心者 ポインタについて...
-
配列内の文字間を排他的論理和...
-
C言語で特定列だけを抽出して配...
-
std::listの代入について
-
配列で格納したものをmsgboxで...
-
計算結果がものすごく多いんで...
-
乱数ってなんですか?
-
MFC、ダイアログベースでのモー...
-
配列を含む構造体の初期値について
-
自販機での金銭収受を想定した...
-
ガウスの消去法のプログラム
-
配列の制限について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語 配列の長さの上限
-
配列を使わずに、変数名を動的...
-
C# Listを使わずに2次元配列の...
-
【速いブラインドタッチ】手を...
-
配列をEraseしてもメモリが開放...
-
テキストファイルから文字列を...
-
先頭アドレスとは何ですか?
-
配列で格納したものをmsgboxで...
-
複数の選択範囲の行番号を個別...
-
C# 配列の変数宣言について。
-
C++ vectorに配列をプッシュしたい
-
配列を含む構造体の初期値について
-
VBで構造体の配列を関数に渡す...
-
C言語で特定列だけを抽出して配...
-
キーボードのキー配列について
-
ExcelVBAで質問です。離れた二...
-
2次元配列を戻り値とする関数?
-
unsigned char配列への入力の仕方
-
【C言語】配列の中に配列を入れ...
-
Redimした動的配列はEraseする...
おすすめ情報