プログラミング学習記録【10日目】
解釈
みんな大好きソクラテスさんは、無知は罪なり、と言った。
この言葉には続きがあるらしい。
知らないことは罪だ。僕は幼い頃から親にこの言葉を浴び続けられ、知らないことは悪いことなんだ、と思っていた。
今は、知らないからと言って許されることはない、という意味もあると解釈しているが、やはり、無知とは恥ずかしいことなんだ、というイメージのほうが強い。
だから、知ってることがあるとついついマウントをとりたくなってしまう心理もわからなくもない。
こういった考えを、「いや、間違ってんで?」と説いているのが続く「知は空虚なり」というお言葉である。
こっちは簡単で、知っているだけではなんの意味もない、という意味だろう。最後の「英知持つもの英雄なり」がその証左だ。
知識というものは、知らないなら土俵にすら上がっておらず、知っているだけでは無価値なもので、その知識を活かし行動して初めて価値を持つものだ、と解釈に至るまでに随分と時間がかかった。
これは現時点の僕の解釈だ。人によって解釈は違うだろうし、これから社会の荒波に揉まれる中で、色を変え形を変え、訴えかけることも変わっていくのだろう。
ただ今は、この解釈を大切にしたい。
言葉を噛み締め、やっと出てきた初めての味なのだ。20代のガキの頃の自分が、ない頭を絞って、頭のいい人のお言葉の一端に手を触れてみた、その行為が、今の自分にとっては意義のあることのように思えてならないのだ。
だから、バイト中にマウントとってくるめんどくさいフリーターも、大きな心を持って受け流してあげなければならない。この人はまだ「知は空虚」に至ってないだけなのだ。僕のほうがおっとなー!
2.03.多次元配列
気を取り直してお勉強。
2次元配列は完全に行列。
2次元の表を取り扱う際に便利、らしい。
2次元配列の宣言は
vector<vector<要素の型>> 変数名(縦の要素数, vector<変数の型> (横の要素数));
で行う。
各要素にアクセスする際は、
変数名.at(上から何番目か).at(左から何番目か)
要素数の取得は縦の要素数と横の要素数で取得方法が違い、
縦の場合
変数名.size()
横の場合
変数名.at(0).size()
とする。
3次元配列は、2次元配列の配列で、同じ要素数の行列がいくつもあるイメージ。
vector<vector<vector<要素の型>>> 変数名(行列の個数, vector<vector<要素の型>>(縦の要素数, vector<要素の型>(横の要素数)));
で宣言する。
4次元以上も同様に宣言するが、イメージが難しい笑。
3次元配列を本に見立て、本の冊数が増えるのが4次元、その本の束が複数存在するのが5次元…であっているだろうか。本屋さんになってしまう。
行列の場合、
vector<型> 変数名(H * W)
と宣言することもできる。このとき、y行x列目の要素にアクセスする場合は
変数名.at(y * W + x)
とすれば良い。
EX.18.ゲーム大会
N人が参加するゲーム大会でM回試合が行われた。
入力は、
人数 試合回数
勝った人 負けた人 (第1試合)
…
勝った人 負けた人 (第M試合)
で行われる。この情報から、試合結果の表を作成する。なお、試合が行われていないペアについては”-”を出力する。
N,Mについてはサンプルプログラムで入力が終わっていて、ついでに勝敗の結果の配列も完成済み。よってやることは、人数分の初期値”-”の行列を作り、結果の配列からペアの要素を読み取り、それぞれ○と×を入れていく。まずは行列の作成部分。
vector<vector<char>> chart(N, vector<char>(N, '-'));
// 記号を扱いたいのでchar型。
// 変数名は”表”なのでchart。
// 初期値で - を渡してあるので(N * N)の "-"が出現してくれるはず。
// char型だから ' 'で括る。
次に、勝敗の配列から-だらけの行列に○×を入れていく。
for (int i = 0; i < M; i++)
{
A.at(i)--;
B.at(i)--;
// 人数は1~Nまであったが、プログラムは0から始まるので要素から1引いておく
chart.at(A.at(i)).at(B.at(i)) = 'o';
chart.at(B.at(i)).at(A.at(i)) = 'x';
//入力があったペアごとに-を○と×に変換していく
}
最後に出力部分。
for (int i = 0; i < N; i++) //完成した行列を出力する こっちは行
{
for (int j = 0; j < N; j++) //こっちは列
{
cout << chart.at(i).at(j);
if (j == N - 1) //N-1が最後の要素
{
cout << endl; //最後の要素なら改行を入れる
}
else
{
cout << " "; //最後の要素でないならスペースを入れる
}
}
}
コードの全形は以下。
#include <bits/stdc++.h>
using namespace std;
int main()
{
int N, M;
cin >> N >> M;
vector<int> A(M), B(M);
for (int i = 0; i < M; i++)
{
cin >> A.at(i) >> B.at(i);
}
vector<vector<char>> chart(N, vector<char>(N, '-'));
// 記号を扱いたいのでchar型。
// 変数名は”表”なのでchart。
// 初期値で - を渡してあるので(N * N)の "-"が出現してくれるはず。
// char型だから ' 'で括る。
for (int i = 0; i < M; i++)
{
A.at(i)--;
B.at(i)--;
// 人数は1~Nまであったが、プログラムは0から始まるので要素から1引いておく
chart.at(A.at(i)).at(B.at(i)) = 'o';
chart.at(B.at(i)).at(A.at(i)) = 'x';
//入力があったペアごとに-を○と×に変換していく
}
for (int i = 0; i < N; i++) //完成した行列を出力する こっちは行
{
for (int j = 0; j < N; j++) //こっちは列
{
cout << chart.at(i).at(j);
if (j == N - 1) //N-1が最後の要素
{
cout << endl; //最後の要素なら改行を入れる
}
else
{
cout << " "; //最後の要素でないならスペースを入れる
}
}
}
}
こいつで提出。
ここのところプログラムが長くなってきて、そういえば設定していなかったVScodeの拡張機能やらなんやらをサブ機でもいじってみた。
非常にスグレモノで、括弧の色分けやら段落の色付けやらで非常に助かったのだが、中でも一番良いアップデートだったのがコード自動整形。
勝手に変換されるので括弧の表記などが今までと異なっているが、おそらくこちらのほうが一般的なのだろうと思いあえて設定はいじらなかった。
嫌になってきたら頑張って変えてみようと思う。