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

第8話 自然配列担当課長と表示担当課長を雇う!

コード例

#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 = 8;//具体的な数字を使うのではなく、 n を使うと汎用性のあるプログラムになる!

//部長の任務は社長の仕事の一部を引き受け、
//社員(部の社員)に仕事を命令することです。
void 部長(int a[n][n]);

void 自然配列担当課長(int a[n][n]);

void 表示担当課長(int a[n][n]);


//fの任務は各対角線部分を点対称移動させることである
void f(int a[n][n]);

//gの任務は各対角線部分を点対称移動させることである
void g(int a[n][n]);

//hの任務は各対角線部分を点対称移動させることである
void h(int a[n][n]);

int main() {//私は社長だ。

  int a[n][n];//2次元配列を定義(用意)した。

  部長(a);//部長に統率を依頼 

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

  return 0;//int main() を終わるためのお呪い

}

void 部長(int a[n][n]) {

  
自然配列担当課長(a);

  表示担当課長(a);

  f(a);//2次元配列を対角線データ交換関数に送る

  cout << endl;

  
表示担当課長(a);

  g(a);//2次元配列を対角線データ交換関数に送る

  cout << endl;

  
表示担当課長(a);

  h(a);//2次元配列を対角線データ交換関数に送る

  cout << endl;

  
表示担当課長(a);

}

void 自然配列担当課長(int a[n][n]) {

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

      a[i][j] = n * i + j + 1;//自然配列を2次元配列に収納

    }

  } 

}

void 表示担当課長(int a[n][n]) {

  //自然配列を体裁を整えてコンソール画面に表示する
  for (int i = 0; i < n; i++) {

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

      if (a[i][j] < 10)cout << " ";

      cout << a[i][j] << " ";

    }

    cout << endl;

  }

}


//fの任務は対角線部分を点対称移動させることである
void f(int a[n][n]) {

  //対角線点対称移動
  for (int i = 0; i < n / 2; i++) {

    int u;//交換のための受け皿

    //対角線部分を点対称移動する作業を始める
    u = a[i][i];
    //a[i][i]のデータがa[n - i][n - i]のデータに上書きされる前に
    //uにa[i][i]のデータを保存

    a[i][i] = a[n - 1 - i][n - 1 - i];
    //a[i][i]のデータをa[n - 1 - i][n - 1 - i]のデータで上書き

    a[n - 1 - i][n - 1 - i] = u;
    //a[i][i]の元データでa[n - 1 - i][n - 1 - i]のデータを上書き
    //対角線部分を点対称移動する作業を終了


    //逆対角線部分を点対称移動する作業を始める
    u = a[i][n - 1 - i];
    //a[i][n - 1 - i]のデータがa[n - 1 - i][i]のデータに上書きされる前に
    //uにa[i][n - 1 - i]のデータを保存

    a[i][n - 1 - i] = a[n - 1 - i][i];
    //a[i][n - 1 - i]のデータをa[n - 1 - i][i]のデータで上書き

    a[n - 1 - i][i] = u;
    //a[i][i]の元データでa[n - 1 - i][n - 1 - i]のデータを上書き
    //逆対角線部分を点対称移動する作業を終了

  }

}

//gの任務は緑部分を線対称移動させることである
void g(int a[n][n]) {

  for (int i = 0; i < n / 2; i++) {
    //1列目から4列までの上下対称移動

    int u;//交換のための受け皿

    u = a[i][(2 + i) % (n / 2)];
    // a[i][(2 + i) % (n / 2)]のデータがa[n - 1 - i][(2 + i) % (n / 2)]
    //のデータに上書きされる前にuに保存

    a[i][(2 + i) % (n / 2)] = a[n - 1 - i][(2 + i) % (n / 2)];
    //a[i][(2 + i) % (n / 2)]のデータをa[n - 1 - i][(2 + i) % (n / 2)]のデータで上書き

    a[n - 1 - i][(2 + i) % (n / 2)] = u;
    //a[n - 1 - i][(2 + i) % (n / 2)]のデータをa[i][(2 + i) % (n / 2)]の元データで上書き

    //1列目から4列までの上下対称移動終了


    //5列目から8列までの上下対称移動

    u = a[i][n - 1 - (2 + i) % (n / 2)];
    //a[i][(n - 1 - (2 + i) % (n / 2)]のデータがa[n - 1 - i][n - 1 - (2 + i) % (n / 2)] // のデータに上書きされる前にuに保存

    a[i][n - 1 - (2 + i) % (n / 2)] = a[n - 1 - i][n - 1 - (2 + i) % (n / 2)];
    //a[i][n - 1 - (2 + i) % (n / 2)]のデータをa[n - 1 - i][n - 1 - (2 + i) % (n / 2)]のデータで上書き

    a[n - 1 - i][n - 1 - (2 + i) % (n / 2)] = u;
    //a[n - 1 - i][n - 1 - (2 + i) % (n / 2)]のデータをa[i][n - 1 - (2 + i) % (n / 2)]の元データで上書き

    //5列目から8列までの上下対称移動終了

  }
  //緑の部分の交換終了

}

//hの任務は明るい紫部分を線対称移動させることである
void h(int a[n][n]) {

  //明るい紫色の部分の交換を始める
  for (int i = 0; i < n / 2; i++) {

    int u;//交換のための受け皿

    //1行目から4行目の左右対称移動

    u = a[i][(3 + i) % (n / 2)];
    //a[i][(3 + i) % (n / 2)]のデータがa[i][n - 1 - ((3 + i) % (n / 2))]
    // のデータ上書きされる前にuに保存

    a[i][(3 + i) % (n / 2)] = a[i][n - 1 - ((3 + i) % (n / 2))];
    //a[i][(3 + i) % (n / 2)]のデータをa[i][n - 1 - ((3 + i) % (n / 2))]のデータで上書き

    a[i][n - 1 - ((3 + i) % (n / 2))] = u;
    //a[i][n - 1 - ((3 + i) % (n / 2))]のデータをa[i][(3 + i) % (n / 2)]の元データで上書き

    //1行目から4行目の左右対称移動終了


    //5行目から8行目までの左右対称移動

    u = a[n - 1 - i][(3 + i) % (n / 2)];
    //a[n - 1 - i][(3 + i) % (n / 2)]のデータがa[n - 1 - i][n - 1 - ((3 + i) % (n / 2))]
    // のデータ上書きされる前にuに保存

    a[n - 1 - i][(3 + i) % (n / 2)] = a[n - 1 - i][n - 1 - ((3 + i) % (n / 2))];
    //a[n - 1 - i][(3 + i) % (n / 2)]のデータをa[n - 1 - i][n - 1 - ((3 + i) % (n / 2))]のデータで上書き

    a[n - 1 - i][n - 1 - ((3 + i) % (n / 2))] = u;
    //a[n - 1 - i][n - 1 - ((3 + i) % (n / 2))]のデータをa[n - 1 - i][(3 + i) % (n / 2)]の元データで上書き

    //5行目から8行目までの左右対称移動終了
  }
  //明るい紫色の部分の交換終了

}

部長と課長の構造化ができました。

対角線担当社員と緑担当社員と明るい紫担当職員も

構造化したいところです。

組織を改編してもう少し構造をはっきりさせたいところです。

平社員の仕事も考えたいところです。

1日経って、第8話の問題が見えました。

void 自然配列担当課長(int a[n][n]);

void 表示担当課長(int a[n][n]);

は、課長という名前がついていますが、

実際には2人がやっている労働は現場労働ですし、

部下が一人もいません。

そこで、2人を平社員に降格して、

その2人を統率する課長を設けます。

void 自然配列担当
社員(int a[n][n]);

void 表示担当
社員(int a[n][n]);

降格したので当然社員名も変わります。

第2章第3話で学んだ通り、名前を呼ぶだけで仕事の依頼になりますから、

  自然配列担当社員(a);

  表示担当社員(a);

新設された課長の仕事はこれだけです。

  f(a);//2次元配列を対角線データ交換関数に送る

  cout << endl;

  表示担当課長(a);

  g(a);//2次元配列を対角線データ交換関数に送る

  cout << endl;

  表示担当課長(a);

  h(a);//2次元配列を対角線データ交換関数に送る

  cout << endl;

  表示担当課長(a);

についても3文の指示を担当する課長を新設することにしましょう。

f・g・h の3つの交換作業は、それぞれ独立した仕事なので、

それぞれを統率する課長を1人ずつ配置します。


課長が4人になりますから、名称は課長1、課長2、課長3、課長4とすることにしましょう。

実行画面


1 2 3 4 5 6 7 8
9 10 11 12 13 14 15 16
17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 32
33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48
49 50 51 52 53 54 55 56
57 58 59 60 61 62 63 64

64 2 3 4 5 6 7 57
9 55 11 12 13 14 50 16
17 18 46 20 21 43 23 24
25 26 27 37 36 30 31 32
33 34 35 29 28 38 39 40
41 42 22 44 45 19 47 48
49 15 51 52 53 54 10 56
8 58 59 60 61 62 63 1

64 2 59 4 5 62 7 57
9 55 11 52 53 14 50 16
41 18 46 20 21 43 23 48
25 34 27 37 36 30 39 32
33 26 35 29 28 38 31 40
17 42 22 44 45 19 47 24
49 15 51 12 13 54 10 56
8 58 3 60 61 6 63 1

64 2 59 5 4 62 7 57
16 55 11 52 53 14 50 9
41 23 46 20 21 43 18 48
25 34 30 37 36 27 39 32
33 26 38 29 28 35 31 40
17 47 22 44 45 19 42 24
56 15 51 12 13 54 10 49
8 58 3 61 60 6 63 1










第7章第7話へ 第7章第9話へ

本講義トップへ