第15講 関数の再帰的呼び出しによる順列の作成
第2話 関数の再帰的呼び出しが向くプログラム
順列が、何故関数の再帰的呼び出しが向いているのか、
理由を説明することによって、
いかなる問題やプログラムなら関数の再帰的呼び出しが向いているのかを考えてみましょう。
さて、5次順列を考えるとします。
5のセル(枠)を用意して、そこに1から5の数字を入れていきます。
各セルの特徴は何でしょうか。
どのセルも、
1から5のいずれかの数字が入り、他のセルと重複してはならない
という同じ原則があります。
つまり、各セルの条件・構造はまったく同じです。
このように条件が同じものは、関数の再帰的呼び出しが向いているのです。
同じ条件の繰り返し、つまり、同じことの繰り返しです。
私は、いつも関数の再帰的呼び出しを入れ子式人形の例で説明します。
ロシアのマトリョーシカ人形(ウィキペディアより)や七福神人形は、入れ子式人形になっています。
関数が自分を呼び出すのは、外側の人形がひとつ内側の人形を呼び出すのに相当します。
自分が自分を呼び出すといっても、
基本的に同じ形態の内側にある人形を呼び出しているのです。
自己再帰と呼ぶ場合もありますが、
あくまで自分と基本的に同じ仕組みをした入れ子式人形の内側への進展です。
自分が自分を呼び出すとき、呼び出す自分と呼び出される自分は、
入れ子式人形とそのひとつ内側の人形に対応します。
呼び出す自分が外側の人形であり、呼び出される自分は内側の人形なのです。
同じ自分でも異なる人形です。
次元が違うというのは、同じ形態の入れ子式人形であっても、
内側の人形から見ればひとつ外側の人形、
外側の人形から見ればひとつ内側の人形というように、
違う人形であることを言っています。
入れ子式の人形の話はもちろん比喩ですが、
まさに関数の再帰的呼び出し=関数の自己再帰と同じ構造をもっています。
より内なる自己へと遡及していって一番小さい人形にたどり着いたときに、
自分の本質を発見するのです。
#include<iostream>
using namespace std;
int f(int w);
int i;
int main(){
i=0;
cout<<"1から3までの和:"<<f(0)<<endl;
}
int f(int w){
i++;
w+=i; //w=w+i;の簡略表現
if(i+1<4)w=f(w);
return(w);
}
このプログラムは、
一番内側の人形=3番目の人形にたどり着いたときにはじめて自己の本質である答え6を発見するのです。
int f(0){
i=0+1;
w=0+1;
if(1+1<4)w=f(1);
int f(1){
i=1+1;
w=1+2;
if(2+1<4)w=f(3);
int f(3){
i=2+1;
w=3+3;
if(3+1<4)w=f(4);//実行されない
return(6);//w=6です。
}
return(6);//w=6です。 ①
}
return(6);//w=6です。 ②
}
return(6); ③
}
次元の違いの意味が少しお分かりになったのではありませんか。
さて、関数の再帰的呼び出しが向いている問題は、同じこと・条件の繰り返しとになっているものです、が結論です。
第1話へ 第3話へ
C言語 C++講義第1部へ
VB講義へ
VB講義基礎へ
vc++講義へ第1部へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)