マルチスレッド版数独自動生成ソフトC++コードを題材とする超初心者のためのVisual Studio C++講義
第9章 関数の再帰的使用

第7話 トレースに入る前の手による体験

プログラムコード再掲

#include<iostream>//インクルードファイルiostreamの読み込み

#include<conio.h>//while(!_kbhit());を使うためのお呪い

#include<string> //文字列変数を使えるようにするために組み込む

#include <iomanip> //setprecisionを使えるように組み込む

#include <cmath>//powなどを使うときに必要

#include <ctime>//time()(←現時刻発生する関数)を使うために必要

using namespace std;//coutを使うときに必要なお呪い

const int n = 5;//具体的な数字を使うのではなく、 n を使うと汎用性のあるプログラムになる!

void f(int s);//順列生成関数←引数名をgからsに変更(2026年3月19日)

int a[25]; //将来5次魔方陣まで生成できるように25に変更

int cn = 0; //anに変更 変更理由はnuberの頭文字nは整数を表す場合が多いからです

int main() {

              f(0);//順列生成関数

              cout << endl << "生成された順列は" << cn << "個です。" << endl;//←2026年3月19日訂正

              while (!_kbhit());//待機させるための命令

              return(0);

}

void f(int s) {

              int h;

              for (int i = 0; i < n; i++) {

                            if (s == 0)a[s] = i + 1;

                            h = 1;

                            if (s > 0) {

                                          for (int j = 0; j < s; j++) {

                                                        if (a[j] == i + 1) {

                                                                      h = 0;

                                                                      break;

                                                        }

                                          }

                                          if (h == 1)a[s] = i + 1;

                            }

                            if (h == 1) {

                                          if (s + 1 < n) {

                                                        f(s + 1);

                                          }

                                          else {

                                                        for (int j = 0; j < n; j++)cout << a[j];

                                                        cout << " ";

                                                        cn++;

                                                        if (cn % 10 == 0)cout << endl;

                                          }

                            }

              }

}



まず、トレースに入る前に手による順列の作成を体験していただきます。

そして、再帰でやっていることはそれと同じことをやっているだけなのです。

ポイントになる点はsが変わることが部屋移動なのであるということです。

手でやるときは無意識にわかっていますが、

部屋を移動していることを意識化しておくことが肝要です。

では、添付エクセルファイルを開いてください。

ダブルクリックして保存してから開いてください。



そして、ご自分で順列を作る過程を体験していただきたいのです。


大変面倒な操作ですが、最後までやってほしいのです。

欄を埋めていく際に今どの部屋にいるのかを意識しながらやってほしいのです。

修学旅行では部屋移動は普通にやっていましたが、

sが変わることが部屋移動です。

そして、それぞれの部屋ごとにfor文があるのです。

もし、欄が足りなくなったらコピペで加えてください。

for文の中にsがあるのではなく、sという世界の中にfor文があるのです。

部屋番号が異なるということは部屋が異なるということです。

sが変わると異世界になると思ってください。

void f(int s)

sが
異世界を規定していて

その中にfor文があるのです。

部屋には出席番号1,2,3の可能性が等しくあるのです。

123 132

213 231

312 321

です。

どの部屋も1,2,3の可能性が等しくあることを体験で会得してほしいのです。

この体験があってこそ次話以降のトレースが初めて理解できるのです。
         






第9章第6話へ 第9章第8話へ

本講義トップへ