(cache) アルゴリズム基礎論演習2009

課題7 「フィボナッチ数(再帰処理)」


内容

  41番目のフィボナッチ数fib(41)を、再帰処理を使う場合と使わない場合とで求めよ。

	フィボナッチ数:fib(n)=fib(n-1)+fib(n-2)  (n≧2)
			fib(0)=0 , fib(1)=1

  ※ fib(0)は「0番目」のフィボナッチ数とする。

  ※ 再帰処理を行う場合の関数 fib1(n) と、行わない場合の関数 fib2(n) を作成し、
    ひとつのプログラムにまとめること。

  ※ fib1(n)とfib2(n)の出力の型は integer とする。

入力

  今回の課題では、入力は無くても構わない。
  例えば、以下のように定数として処理してよい。

  const
	N = 41;

  {~関数を書く~}

  begin
    writeln('再帰あり fib(',N:0,')=',fib1(N)); 
    writeln('再帰なし fib(',N:0,')=',fib2(N)); 
  end.
  任意のフィボナッチ数を出力したい場合は、   n番目のフィボナッチ数を意味するnの値を入力とせよ。   但し、今回の課題ではフィボナッチ数を Integer型 で作成する為、   n ≧ 47 の数値を与えるとオーバーフローする。 Integer型の値域:-2147483648~2147483647 fib(47) = 2971215073

出力

  出力は以下の2つとする。

	・再帰処理(有)で求めた41番目のフィボナッチ数(fib(41))
	・再帰処理(無)で求めた41番目のフィボナッチ数(fib(41))

  再帰処理を使用する方は、出力に時間がかかる。(fib(41)で約10秒)

実行

  入力を設けなかった場合は、コンパイルしたプログラムをそのまま実行すればよい。
  入力を設けた場合は、n=41と入力してフィボナッチ数を求めよ。

ヒント

再帰的プログラム

  再帰処理の方法は、恐らく他の演習で学習済みだと思うが、
  復習の意味も込めて簡単に説明しておく。必要ない学生は読み飛ばして課題を進めてよい。

  再帰処理とは、簡単に言えば「定義した関数の中で、自分自身を関数として呼び出す」処理のことを指す。

  例えば、「階乗の計算」を行う関数を作成しようとする。
  階乗の計算は一般的に式(1)のようにして解く。

    n! = n * (n-1) * (n-2) * … * 1		(1)

  式(1)をプログラムに実装すると、以下のようなfor文を使用した関数になる。

  function fac2(n : integer) : integer; 
  var
	i , sum : integer ;
  begin
	sum := 1;
	for i := 1 to n do
		sum := sum*i ; 
	fac2 := sum;
  end;
  ここで、階乗の計算式を式(2)のように変形する。 n! = n * (n-1)! (2)   これは、例えば5の階乗を求める時、4の階乗の解が分かっていれば   式(3)のようにして解を求めることができることを意味する。 5! = 5 * 4! (3)   4の階乗の解が分からない場合は、3の階乗の解から求め、   3の階乗の解が分からない場合は、2の階乗の解から求め、   2の階乗の解が……   と徐々に掘り下げていけば、   0の階乗の解は1である。   という最も単純な解にたどり着く。   ここから、逆順に処理を戻っていけば、5の階乗の解を導き出すことができる。 5! = 5 * 4! 4! = 4 * 3! 3! = 3 * 2! 2! = 2 * 1! 1! = 1 * 0! 0! = 1 1! = 1 * 1 = 1 2! = 2 * 1 = 2 3! = 3 * 2 = 6 4! = 4 * 6 = 24 5! = 5 * 24 = 120   このような階層的な処理をプログラムに実装すると、以下のようになる。
  function fac1(n : integer) : integer; 
  var
	int : integer;
  begin
	if (n=0) then
		fac1 := 1
	else
		fac1:= n * fac1(n-1);
  end;
  赤字の「自分自身の関数を呼び出す」部分が再帰処理である。   再帰処理を行う際に重要になってくるのが、青字で示した初期条件である。   初期条件を指定しておかないと、再帰処理は潜ったっきり帰ってこなくなるので注意すること。

出力例

  入力を赤字で示した。

  n = 10
  再帰あり fib(10)=55 
  再帰なし fib(10)=55 
  ただし、先に述べたとおり、今回の課題では入力はなくても構わない。