マルチスレッド版数独自動生成ソフトC++コードを題材とする超初心者のためのVisual Studio C++講義
第7章 関数の学習
第6話 明るい紫部分を左右に線対称移動して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 を使うと汎用性のあるプログラムになる!
//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次元配列を定義(用意)した。
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
a[i][j] = n * i + j + 1;//自然配列を2次元配列に収納
}
}
//自然配列を体裁を整えてコンソール画面に表示する
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(a);//2次元配列を対角線データ交換関数に送る
cout << endl;
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;
}
g(a);//2次元配列を対角線データ交換関数に送る
cout << endl;
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;
}
h(a);//2次元配列を対角線データ交換関数に送る
cout << endl;
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;
}
while (!_kbhit());//待機させるための命令
return 0;//int main() を終わるためのお呪い
}
//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行目までの左右対称移動終了
}
//明るい紫色の部分の交換終了
}
第6章第12話に比べればわかりやすくなりましたが、
まだまだ、社長が仕事をしすぎてきます。
そこで、部長を採用して仕事の一部を部長に移し、
階層をもう一段階深めます。
//部長の任務は社長の仕事の一部を引き受け、
//社員(部の社員)に仕事を命令することです。
void 部長(int a[n][n]);
具体的には
int a[n][n];//2次元配列を定義(用意)した。
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
a[i][j] = n * i + j + 1;//自然配列を2次元配列に収納
}
}
//自然配列を体裁を整えてコンソール画面に表示する
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(a);//2次元配列を対角線データ交換関数に送る
cout << endl;
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;
}
g(a);//2次元配列を対角線データ交換関数に送る
cout << endl;
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;
}
h(a);//2次元配列を対角線データ交換関数に送る
cout << endl;
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;
}
青色の部分をすべて部長の仕事にしてください。
第7章第5話へ 第7章第7話へ
本講義トップへ