第10講 関数の学習
第7話 重複判定プログラムの解説
解答例
#pragma once
char a[4][4];
・
・
・
#pragma endregion
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^
e) {
f1();
f2();
}
void f1(void){
char i;
char j;
String^ w=L"";
for(i=0;i<4;i++){
for(j=0;j<4;j++){
a[i][j]=4*i+j+1;
if(a[i][j]<10)w=w+L"0"+(a[i][j]).ToString()+L"
";
if(a[i][j]>=10)w=w+(a[i][j]).ToString()+L"
";
}
w=w+L"\n";
}
label1->Text=w;
}
void f2(void){
char i;
char j;
char b[16];
String^ w=L"";
char h=0;
char k;
for(i=0;i<16;i++)b[i]=0;
for(i=0;i<4;i++){
for(j=0;j<4;j++){
k=a[i][j]-1;
if(b[k]==1){
h=1;
break;
}
else{
b[k]=1;
}
}
if(h==1)break;
}
if(h==0)label2->Text=L"数字の重複はありませんでした。";
if(h==1)label2->Text=L"数字の重複がありました。";
}
};
}
(コピーペースト用
#pragma once
char a[4][4];
・
・
・
#pragma endregion
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
f1();
f2();
}
void f1(void){
char i;
char j;
String^ w=L"";
for(i=0;i<4;i++){
for(j=0;j<4;j++){
a[i][j]=4*i+j+1;
if(a[i][j]<10)w=w+L"0"+(a[i][j]).ToString()+L" ";
if(a[i][j]>=10)w=w+(a[i][j]).ToString()+L" ";
}
w=w+L"\n";
}
label1->Text=w;
}
void f2(void){
char i;
char j;
char b[16];
String^ w=L"";
char h=0;
char k;
for(i=0;i<16;i++)b[i]=0;
for(i=0;i<4;i++){
for(j=0;j<4;j++){
k=a[i][j]-1;
if(b[k]==1){
h=1;
break;
}
else{
b[k]=1;
}
}
if(h==1)break;
}
if(h==0)label2->Text=L"数字の重複はありませんでした。";
if(h==1)label2->Text=L"数字の重複がありました。";
}
};
)
解説
はじめ
1 | × |
2 | × |
3 | × |
4 | × |
5 | × |
6 | × |
7 | × |
8 | × |
9 | × |
10 | × |
11 | × |
12 | × |
13 | × |
14 | × |
15 | × |
16 | × |
としておいて、1から16のどれかの数字があったら×を○に変更していきます。
例えば、
1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 |
の場合は
1 | ○ |
2 | ○ |
3 | ○ |
4 | ○ |
5 | ○ |
6 | ○ |
7 | ○ |
8 | ○ |
9 | ○ |
10 | ○ |
11 | ○ |
12 | ○ |
13 | ○ |
14 | ○ |
15 | ○ |
16 | ○ |
すべてに丸が1個ずつ付きます。
ところが、
1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 |
13 | 14 | 15 | 1 |
の場合は、
1 | ○ | ○ |
2 | ○ | |
3 | ○ | |
4 | ○ | |
5 | ○ | |
6 | ○ | |
7 | ○ | |
8 | ○ | |
9 | ○ | |
10 | ○ | |
11 | ○ | |
12 | ○ | |
13 | ○ | |
14 | ○ | |
15 | ○ | |
16 | × |
となり、1のところに○が2ついてしまいます。
○が2つ以上付いたら数字が重複しています。
プログラムでは、×を0に対応させ、○を1に対応させています。
for(i=0;i<16;i++)b[i]=0;で
1 | × |
2 | × |
3 | × |
4 | × |
5 | × |
6 | × |
7 | × |
8 | × |
9 | × |
10 | × |
11 | × |
12 | × |
13 | × |
14 | × |
15 | × |
16 | × |
の状態を実現しています。
ただし、例えば、b[5-1]=0は
5 | × |
に対応します。b[i]の添え字は0から始まるので1個ずれます。
for(i=0;i<4;i++){
for(j=0;j<4;j++){
k=a[i][j]-1;
if(b[k]==1){
h=1;
break;
}
else{
b[k]=1;
}
}
if(h==1)break;
}
if(h==0)label2->Text=L"数字の重複はありませんでした。";
if(h==1)label2->Text=Text=L"数字の重複がありました。";
をトレースしましょう。
j | 0 | 1 | 2 | 3 | |
i | |||||
0 | 1 | 2 | 3 | 4 | |
1 | 5 | 6 | 7 | 8 | |
2 | 9 | 10 | 11 | 12 | |
3 | 13 | 14 | 15 | 1 |
の場合は
i | j | セル内の数字 |
0 | 0 | 1 |
0 | 1 | 2 |
0 | 2 | 3 |
0 | 3 | 4 |
1 | 0 | 5 |
1 | 1 | 6 |
1 | 2 | 7 |
1 | 3 | 8 |
2 | 0 | 9 |
2 | 1 | 10 |
2 | 2 | 11 |
2 | 3 | 12 |
3 | 0 | 13 |
3 | 1 | 14 |
3 | 2 | 15 |
3 | 3 | 1 |
です。b[k]のkはk=a[i][j]-1ですから、セルの数から1引いた数です。
したがって、
b[1-1]=0→b[1-1]=1
b[2-1]=0→b[2-1]=1
b[3-1]=0→b[3-1]=1
b[4-1]=0→b[4-1]=1
b[5-1]=0→b[5-1]=1
b[6-1]=0→b[6-1]=1
b[7-1]=0→b[7-1]=1
b[8-1]=0→b[8-1]=1
b[9-1]=0→b[9-1]=1
b[10-1]=0→b[10-1]=1
b[11-1]=0→b[11-1]=1
b[12-1]=0→b[12-1]=1
b[13-1]=0→b[13-1]=1
b[14-1]=0→b[14-1]=1
b[15-1]=0→b[15-1]=1
までは
if(b[k]==1){
h=1;
break;
}
else{
b[k]=1;
}
のelse文の方が実行されてきましたが、
1行目b[1-1]=0→b[1-1]=1によって、b[0]=1となっていますので、b[1-1]のとき、はじめてif文の方が実行されて、
h=1;
break;
となります。break;によって中のfor文(for(j=0;j<4;j++))が強制終了されます。
さらにこのとき、if(h==1)break;によって外のfor文(for(i=0;i<4;i++))が強制終了されます。
最後にif(h==1)label2->Text=Text=L"数字の重複がありました。";によってlabel2に『数字の重複がありました』
と表示されることになります。
実際に関数f1に
void f1(void){
char i;
char j;
String^ w=L"";
for(i=0;i<4;i++){
for(j=0;j<4;j++){
a[i][j]=4*i+j+1;
if(a[i][j]==16)a[i][j]=1;
if(a[i][j]<10)w=w+L"0"+(a[i][j]).ToString()+L"
";
if(a[i][j]>=10)w=w+(a[i][j]).ToString()+L"
";
}
w=w+L"\n";
}
label1->Text=w;
}
if(a[i][j]==16)a[i][j]=1;の1行付け加え、ビルドして実行をクリックすると、
となります。そのほか、いろいろ実験してみてください。
元に戻って
1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 |
のような場合は、
1 | ○ |
2 | ○ |
3 | ○ |
4 | ○ |
5 | ○ |
6 | ○ |
7 | ○ |
8 | ○ |
9 | ○ |
10 | ○ |
11 | ○ |
12 | ○ |
13 | ○ |
14 | ○ |
15 | ○ |
16 | ○ |
すなわち
b[1-1]=0→b[1-1]=1
b[2-1]=0→b[2-1]=1
b[3-1]=0→b[3-1]=1
b[4-1]=0→b[4-1]=1
b[5-1]=0→b[5-1]=1
b[6-1]=0→b[6-1]=1
b[7-1]=0→b[7-1]=1
b[8-1]=0→b[8-1]=1
b[9-1]=0→b[9-1]=1
b[10-1]=0→b[10-1]=1
b[11-1]=0→b[11-1]=1
b[12-1]=0→b[12-1]=1
b[13-1]=0→b[13-1]=1
b[14-1]=0→b[14-1]=1
b[15-1]=0→b[15-1]=1
b[16-1]=0→b[16-1]=1
からh=1は1度も実行されませんので、char h=0;でしたからhは0で、
if(h==0)label2->Text=L"数字の重複はありませんでした。";
によって、label2は『数字の重複はありませんでした。』と表示されます。
初心者のためのJava 入門 基礎から応用まで
初心者のための VC++による C言語 入門 C++ 入門 基礎から応用まで第1部
初心者のための VC++による C言語 入門 C++ 入門 基礎から応用まで第2部
初心者のための VC++による C言語 入門 C++ 入門 基礎から応用まで第3部
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすい vb 入門 vba 入門 基礎から応用まで 第1部
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座へ