第9講 関数の再帰的使用
第2話 関数の再帰的使用の具体例
ここでは、階乗を求めるソフトを作って、関数の再帰的使用の具体例を提示していきましょう。
まず、次のようなForm1を作ってください。
そして、実行をダブルクリックして次のようにコーティングしてください。
#pragma endregion
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^
e) {
int a;
a=int::Parse(textBox1->Text);
a=f(a);
textBox2->Text=a.ToString();
}
int f(int a){
if(a==1)return a;
a=a*f(a-1);
return a;
}
};
}
実行画面例
このプログラミングで注目は、f(a-1)です。
関数fが自分自身であるfを呼び出しています。
このような使用方法を、関数の再帰的使用または関数の自己再帰といいます。
入れ子式人形のように、どんどんさらなる自己の内に遡及していっているのです。
自分とは何か、の探求を繰り返していく内に、入れ子式人形の一番小さい人形にたどり着くわけです。
7!とは、何かの問いにa*f(a-1); によって、7×6!と答えます。
そして、次の問い では6!とは何か、に対して
a*f(a-1); によって、6!=6×5!であると答えます。
そして、第3の問い それでは5!とは?に対して、
a*f(a-1); によって、5!=8×4!
と答えます。
同じ問いを繰り返している内に、
ついに最後の入れ子式人形にたどり着きます。
1!です。この最後の問いにif(a==1)return a; によって1であると答えています。
a=1なら1のまま返しなさいですから。
一番小さい入れ子式人形までいったら、今度は逆の途ををたどります。
一番小さい人形から一番大きい人形への旅路を戻ります。
1!とは1です。
よって、2!とは2×1!=2×1=2です。
すると、3!は3×2!=3×2=6です。
以下同様に
4!は、4×3!=4×6=24
5!は、5×4!=5×24=120
6!は、6×5!=6×120=720
7!は、7×6!=7×720=5040
によって、7!の答えを出しています。
つまり、
7!とは?
6!とは?
5!とは?
4!とは?
3!とは?
2!とは?
1!とは?
と遡及していって、一番小さい人形1!にたどり着き、
1!とは1であると答え、
逆遡及の途が始まります。
2!とは2×1!=2×1=2
3!とは3×2!=3×2=6
4!とは4×1!=4×6=24
5!とは5×4!=5×24=120
6!とは6×5!=6×120=720
7!とは7×6!=7×720=5040
真の自分とは何か、の問いを遡及的に繰り返し、どんどん自分を覆っている化けの皮をはがしていって一番核心(本当の自分)にたどり着いたら、
逆の旅に出て今の偽りの自分を説明します。
会社ではいい人を装っているが、家では暴君、いったいその人の本質は?
これらの矛盾する自分を説明するためには、自分の本当の偽りのない姿をさらけ出して(遡及して)、
暴君やいい人であるという現象を見つめ直す(逆遡及)必要があります。
この遡及と逆遡及こそが、関数の再帰的使用です。
入れ子式人形の一番大きい人形から、
入れ子式人形の一番小さい人形にたどり着いて、その人形の正体を暴き出したら、
逆遡及していき、ひとつ上の人形の正体を解明していく方法です。
int f(int a){
if(a==1)return a;
a=a*f(a-1);
return a;
}
によって、確かに自分自身を呼び出しています。
言い換えれば、より深い自分の内に入っていっていますが、
入れ子式の外の人形と内の人形が別の人形であるように、
同じfでありながら別次元の自分です。
具体的にはf(5)とf(4)は、同じfですが、f(4)の方がより深い位置にある人形です。
TextBoxに7を入れた場合は、
7!すなわちf(7)からはじめ、
6!すなたちf(6)へ
5!すなたちf(5)へ
4!すなたちf(4)へ
3!すなたちf(3)へ
2!すなたちf(2)へ
1!すなたちf(1)へ
と遡及の旅をしますが、
f(7)、f(6)、f(5)、f(4)、f(3)、f(2)、f(1)は別の人形です。
同じfでも別次元の関数が立ち上がっていると思った方がよいわけです。
次の課題です。順列
123,132,213,231,312,321
を作り出すプログラムを考えてみましょう。
最初は、for文などでこれを実現してみましょう。
3つの場合に成功したら、4つ、5つ、6つ、7つと増やしてみてください。
for文だと大変煩雑になることがわかると思います。
それに、for文だと下のように一般化することはほぼ不可能ではないでしょうか。
少なくとも私のぼんくらな頭では思いつきません。
実行例
しかし、関数の再帰的使用を利用すると、一般化することもできます。
第1話へ 第3話へ