サイトマップ / C言語講座>出入り口>総目次>目次:再帰>フィボナッチ数列を表示する関数(再帰版)
[10進数を16進表示]←このソース→[フィボナッチ数列(再帰改良版)]
13世紀のイタリアの大数学者フィボナッチ(Leonald Fibonacci)は、ウサギが一定の割合で繁殖して増加する様子を表すために、フィボナッチ数列(Fibonacci Series)を考え出しました。今日は、フィボナッチ数列を例にして、関数の再帰的呼び出し(Recursive Call)について学びます。
フィボナッチ数とは、
- i = 1 の時 Fibo(1) = 1
- i = 2 の時 Fibo(2) = 1
- i = 3 の時 Fibo(3) = 2
- i = 4 の時 Fibo(4) = 3
- i = 5 の時 Fibo(5) = 5
- - - - - - -
- i = n の時 Fibo(n) = Fibo(n - 1) + Fibo(n - 2)
- - - - - - -
Fibo(1)、Fibo(2)を例外として、任意の項はその前の2つの項の合計になっています。結局、下記の数列になります。
1, 1, 2, 3, 5, 8, 13, 21, 34 - - - - - -
この数列は古くから不思議な数列として知られていました。アブラナの種からは二葉が出てきます。クローバーは三つ葉です。アケビという植物には、三つ葉アケビと五葉アケビの2種類があります。桜、山茶花、松葉牡丹の花弁は5枚です。もっと花弁の数の多い花でも、花弁の数がフィボナッチ数になっていることが多いです。松ボックリやパイナップルのうろこのような突起の数は、フィボナッチ数になっています。植物の花びらや葉の数、種の数、など、植物に関係のある数は、フィボナッチ数である場合が多いことが知られています。
i = n のフィボナッチ数は、 Fibo(n) = Fibo(n - 1) + Fibo(n - 2) です。
この式の右辺は、左辺よりひとつ小さいFibo( )と二つ小さいFibo( )からなっています。Fibo(n)を求めるには、自分よりひとつ小さい自分と、二つ小さい自分を呼び出して、合計すればいいわけです。この関数は再帰的に定義するのが自然です。
フィボナッチ数列の定義を、素直にCのコードにすると、今回のソースプログラムになります。nが大きくなるとフィボナッチ数は非常に大きくなるので、戻り値をunsigned long型にしました。再帰を使うことによって、わかりやすく、かつ、コンパクトなコードを書くことができます。後はソースプログラムのコメントをごらん下さい。 */
#include <stdio.h> #include <stdlib.h> /* exit( )で必要 */ unsigned long Fibo(int n); void main(void); /* nのフィボナッチ数を返す */ unsigned long Fibo(int n) { unsigned long f; /* フィボナッチ数をしまう */ switch (n) { case 1: case 2: /* nが1か2なら */ f = 1L; /* fは1 */ break; default: /* それ以外は再帰呼び出し */ f = Fibo(n - 1) + Fibo(n - 2); break; } return (f); /* fの値をリターン */ } void main(void) { int n; /* nのフィボナッチ数を求める */ printf("1から47迄の整数を入力して下さい\t"); scanf("%d", &n); if(n > 47) { /* n が47より大きければ何もしないで終了 */ printf("数字が大き過ぎます\n"); exit (0); } /* フィボナッチ数を表示 */ printf("\nFibonacci 数は %lu\n", Fibo(n)); } |
/* このプログラムでは、98までのフィボナッチ数を求めます。98のフィボナッチ数は、4204349121です。unsigned long型で表すことのできる最大数は、4294967295ですから、98が限界で、99のフィボナッチ数はこのプログラムでは求められません。
nの値が大きくなると計算時間が急速に増大します。 */
[10進数を16進表示]←このソース→[フィボナッチ数列(再帰改良版)]
/* (C) 2000- YFプロ. All Rights Reserved. */ 提供:C言語講座−それ自体コンパイルできる教材を使った講座です−