第15講 関数の再帰的呼び出しによる順列の作成
第5話 順列作成プログラムの解説1(遙かなるトレースへの旅立ちの前に)

4次を例にしたのでは、トレースが余りにも長くなってしまいますし、
2次では理解するには、本質を理解するのに不十分だと思われますので、3次順列を例にトレースします。
3次順列の総数は6個です。
その6個が生まれる様を追体験します。
今話は、トレースの旅立ち=トレースの第1話です。
少し長くなりますが、旅のお供を最後までお願いします。
プログラミングをする上でトレース(コンピュータの動きをひとつ一つ追う)ことは、譲れない条件です。
もちろん、100次魔方陣作成プログラムの動きとなるとコンピュータは京を遙かに上回る回数の処理を行っていますから、
ひとつ一つ追うトレースは不可能ですから、ある程度の動きを追えたら後はイメージによる理解ということになります。
イメージを掴んでいただくためには、2次では不十分で4次では長すぎるという判断から3次を選びます。
イメージを形成するために譲れない用件であると考えて、是非とも最後までのお付き合いをお願いします。
1行1行丁寧にお読みいただければと思います。

尚、今回行うトレースは第13講 3次魔方陣の自動生成
 第5話 1行1行のトレースその1
 第6話 1行1行のトレースその2
 第7話 1行1行のトレースその3
 第8話 4度目の挑戦でようやく勝利!
 第9話 セルa[1][0]a[1][1]a[1][2]へ
 第10話 セルa[1][2]へ2度目の挑戦
 第11話 セルa[1][2]へ3度目の挑戦
 第12話 栄冠は君へ!
も参照し対比していただければよろしいかと思います。
n×n次魔方陣にするには、n×n次順列を2次元に並べて
それに行・列・対角線の条件を付け加えるだけですから、
魔方陣のトレースは大変参考になるわけです。
そして、for文版より圧倒的に関数の再帰的呼び出しの方が優れているのを体感してください。

では、茨の道を歩み始めましょうといいたいところですが、
その前に各関数main、f1、f2の役割を確認しておきましょう。
mainでは、n次順列のnをキーボードから入力してもらいその値を取得してから、
自分の子分に順列を作成するように命じます。
また、できた順列総数もコンソール画面に表示させる役割も持っています。

関数f1は、このプログラムのもっとも核心部分となる関数です。
関数f1が再帰的に呼び出され、9次順列なら合わせて9つのf1が生まれ出ことになります。
最後のf1が誕生したときには、メモリー上にf1が9つ存在し活動しています。
f1は発生消滅を繰り返し、メモリー上にあるf1の個数は
1→2→3→・・・→9→8→9→・・・→9→8→7→8→9→8→・・・
というように流動します。
たくさんのf1が同時に働いているわけですが、
同じf1でも次元の違うf1です。
次元が違うということがわかりにいとお感じでしたら、
入れ子式人形の比喩を思い出していただければと思います。
1番外側の人形が最初に起動して、1番外側の人形は外側から2番目の人形を呼び出します。
2番目の人形は、さらに3番目の人形を呼び出します。
9次順列の場合一番奥深い9番目の人形までたどり着き、9番目の人形が試行錯誤を繰り返して9次順列を発見するのです。
本当の自分を探し、より深い自分の内部へ遡及していって一番内なる自分にたどり着いたときに初めて自分の本質を発見するのです。
次元が違うとは、入れ子式人形の違いです。
9つの人形が協働することによって初めて順列を発見することができます。
9人の共同作品が9次順列なのです。

関数f2は、9次順列なら一番内側の9番目の人形が順列を発見したときに呼び出され、
9番目の人形が発見した、というより9つの人形が共同作業で発見した順列をコンソールに出力させる任務を与えられています。
あくまで9つの人形の協働発見ですが、f2を呼び出す権限は一番内側の人形=9つめの人形のみに与えられています。
理由は、if文
       if(g+1<n){
         f1(g+1);
       }
       else{
         cn++;
         f2();
       }
にあります。

第4話へ 第6話へ

戻る

C言語 C++講義第1部へ
VB講義へ
VB講義基礎へ

vc++講義へ第1部へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座
初心者のための世界で一番わかりやすいVBA入門講義(基礎から応用まで)