はじめに
前回は配列について見てきた。
参照:配列とは何か Javaプログラミング初心者の記録vol.26
今回も配列についてだが、頭に「2次元」とついている。
この2次元配列についてちょっと根気強く見ていこう。
正直言うと私はちょっと混乱したよ…。
2次元配列とは
前回配列を見たときは、箱をイメージしたと思う。
□□□□□
こんな感じのもの。
「配列」ではこれが一列に一直線に並んでいた。
二次元配列とは、イメージとしては箱が縦横に並んだ状態のようなもの。
□□□□□
□□□□□
□□□□□
□□□□□
これが二次元配列。
マトリックスのようなもの。
行と列で成り立っている。
これも配列と同様に、列と行に0から番号がつく。
以下がその例。
見方は簡単で、[]の左側が行番号、右側が列番号となる。
配列の時は数字は1つだけだったが、2次元配列では箱の数字は2つ使われる。
2次元配列のコード
この2次元配列のコードは以下のように書く。
int [][] Nijigen= new int[3][4];
int・・・整数を表す変数の型
[][]・・・二次元配列なので[]を2つ並べる
Nijigen・二次元配列変数の名前 ここはどんな名前でもいい
new ・・からの箱を作るということ
int・・・整数を表す変数の型
[3]・・・行がいくつ必要かということ。今回は「3」と書いたから3行できた。(横のライン)
[4]・・・列がいくつ必要かということ。今回は「4」と書いたから4行できた。(縦のライン)
分解してみていくと上のような感じ。
配列と2次元配列を比べてみる
配列のコードは
int [] Hairetsu = new int [3];
2次元配列のコードは
int [][] Nijigen= new int[3][4];
違うのは[]の数だけで、プログラムの内容は変わらない。
両方とも、空の箱を作っている。
配列は一直線に箱を並べているところを想像してもらえればいい(縦横どちらでもOK)。
□□□□□
空の箱が何個必要かを書けばいいだけだから配列の場合、[]は1つでいい。
2次元配列は縦横に箱を並べているところを想像。
□□□□□
□□□□□
□□□□□
この場合、縦に何個、横に何個必要か書かなければいけないから2次元配列は[]が2個必要。
2次元配列を使う
では2次元配列のコードを実際に使ってみる。
int [][] Nijigen= new int[3][4];
Nijigen[1][3] = 5;
もしこう書いてあったら、上の図の[1,3]に「5」という数字が入るということ。
2つのforループを使って数値を自動的に入力
int [][] Nijigen= new int[3][4];
全部の空箱に一つ一つ数字を入れていくのは面倒。
2つのforループを使えば自動的に数値を入力することができる。
forは以前見たforループのこと。forループ Javaプログラミング初心者の記録vol.19
早速見てみる。
int [][] Nijigen= new int[3][4];
int A=5;
for(int G =0; G<3; G++){
for(int R=0; R<4; R++){
Nijigen[G][R]=A;
A += 5;
}
}
いったい何が起きたのか。
int A=5と宣言しているから、Aには「5」が入るということがわかる。
今回はこの5が基本となっていく。
次に注目すべきは
for(int G =0; G<3; G++){
for(int R=0; R<4; R++){
Nijigen[G][R]=A;
A += 5;
}
}
一見複雑なように見えるけれど、forの中にforが入っているのがわかるだろうか?
for(){ for(){ } }
色分けしたらわかりやすくなった?
構造がわかれば、後はforループと同じこと。
では1つ1つ見ていく。
外側のforの一回目のループ
まずは外側のfor(int G =0; G<3; G++)に注目。
簡単におさらいすると、forループの使い方は以下の通り。
当てはめてみると…
int G =0・・・初期値
G<3・・・・・ループ処理を続ける条件
G++・・・・・ループ一回の処理につき最後に行われるプログラム
ということになる。
このforループの一回目の処理をまとめると、「Gを0と宣言して初期値に設定し、Gは3より小さいという条件に当てはまるから{}内の処理を行い、{}内の処理が終わった後にG++を行う」となる。
このGは後で出てくるから今は気にしないで。
名前もGじゃなくていい。
要は変数「G」が0から2(3以下の整数)で変化するループを設定しただけ。
とりあえず、Gが0のため条件に合うから{}内の処理を行う。
内側のforの一回目のループ
{}内にも、もう一つforがあるからそれに注目。
for(int R=0; R<4; R++)
これも外側のforと同じ使い方。
「Rを0と宣言して初期値に設定し、Rは4より小さいという条件に当てはまるから{}内の処理を行い、{}内の処理が終わった後にR++を行う」ということ。
初期値のRの値は「0」だから条件に合う。
ということで内側のforの{}内を処理する。
Nijigen[G][R]=A;
A += 5;
「Nijigen[G][R]=A;」は配列のところでもやった形と一緒。
配列とは何か Javaプログラミング初心者の記録vol.26
B[2]=10;
B[0]=32;
別に「G」と「R」じゃなくても「K」だったり「Yeah」でも何でもいいよ。
そしてRにも「0」が入る。
これらを合わせると・・・
Nijigen[0][0]=5;
と内部的に入力され、図の[0,0]には5が入るのである。
そして「A += 5;」が処理されるから、Aに5が足される。
この「+=」は代入演算子。こちらを参照。
for{}内の最後に「R++」の処理が行われるから、ループしたときRは「1」ということ。
そして、ここで内側のforの{}内の処理が終わったから、内側のforの()内のループ一回の処理につき最後に行われるプログラムである「R++」が行われる。
そして内側のforループの処理が行われる。
forが二重になっている場合、内側のforをループした後に外側のforがループする。
矛盾しているように聞こえるかもしれないけど、ちゃんと上からプログラムは処理されてる。
ループの順番
先でも書いたこの構造を見てほしい。
for(){ for(){処理} }
外側のforの()内の条件が満たされると、{}内の処理が行われ、{}内の処理が終わったら先頭に戻ってまたループする。
そしてさらに外側のforの{}内にはforループがある。
内側のforも同じで、()内の条件を満たせば{}内の処理が行われ、{}内の処理が終わったら先頭に戻ってまたループする。
ポイントとなるのは内側のforループの先頭はもちろん内側のforであって、外側のforではないということ。
内側のforループの処理がすべて終わって初めて、外側のforの一回目のループが終わったということ。
私の下手な説明で分かったかな…?
オレンジの部分の処理が全部終わって初めて、外側のforの一回目のループが終了となる。
だからもし、内側のforがループできる条件を満たしているなら、内側のforがループできなくなるまで処理が続けられる。
だから、内側のforの一回目のループが終わったら、内側のforの二回目のループが始まるのである。
内側のforの二回目のループ
for(int R=0; R<4; R++)
for{}内の最後に「R++」の処理が行われるため、ループしたときRは「1」から始まる。
Rが「1」というのは、「R<4」という条件に合うから{}内のプログラムが処理される。
Nijigen[G][R]=A;
A += 5;
Gは「0」のまま。
なぜかというと、外側のforはループしていないからGの値は変わらない。
Rの値は「1」になったから、「1」が代入される。
一回目のループでAに5が足されたから、Aの値は「10」となる。
総合すると…
Nijigen[0][1]=10;
A += 5;
以上のことから、[0,1]の部分には「10」が入るということ。
最後に「A+=5」が計算され、さらに「5」が足される。
for{}内の最後に「R++」の処理が行われる。
前回のとき「R」は「1」だったから、ループしたとき「1」足されてRは「2」ということ。
そしてまたループする。
内側のforの三回目のループ
基本的には繰り返し。
for(int R=0; R<4; R++)
for{}内の最後に「R++」の処理が行われ、Rは「2」になっている。
Rが「2」というのは、「R<4」という条件に合うから{}内のプログラムが処理される。
Nijigen[G][R]=A;
A += 5;
Gは「0」のまま。
Rの値は「2」になったから、「2」が代入される。
2回目のループでAは10になった。
10に5が足されたから、Aの値は「15」となる。
総合すると…
Nijigen[0][2]=15;
A += 5;
以上のことから、[0,2]の部分には「15」が入るということ。
最後に「A+=5」が計算され、さらに「5」が足される。
for{}内の最後に「R++」の処理が行われる。
前回のとき「R」は「2」だったから、ループしたとき「1」足されてRは「3」ということ。
そしてまたループする。
内側のforの四回目のループ
またまた繰り返し。
for(int R=0; R<4; R++)
for{}内の最後に「R++」の処理が行われ、Rは「3」になっている。
Rが「3」というのは、「R<4」という条件に合うから{}内のプログラムが処理される。
Nijigen[G][R]=A;
A += 5;
Gは「0」のまま。
Rの値は「3」になったから、「3」が代入される。
3回目のループでAは15になった。
10に5が足されたから、Aの値は「20」となる。
総合すると…
Nijigen[0][3]=20;
A += 5;
以上のことから、[0,3]の部分には「20」が入るということ。
最後に「A+=5」が計算されてAは「25」になる。
for{}内の最後に「R++」の処理が行われる。
前回のとき「R」は「3」だったから、ループしたとき「1」足されてRは「4」ということ。
そして先頭に戻る。
内側のforの五回目のループ
for(int R=0; R<4; R++)
Rが「5」になったが、これはループが行われる条件である「R<4」を満たしていない。
よって、{}内は処理されず、内側のforループはいったんここで終了となる。
そして内側のforループの処理がすべて終わったので、外側のforループのループ一回の処理につき最後に行われるプログラムが行われ、「G++」が実行されて外側のforループの先頭に戻る。
外側のforの二回目のループ
for(int G =0; G<3; G++)
{}内の処理の一番最後に「G++」が処理されているので、先頭に戻ってきたときにはGは0から「1」に変わっている。
Gが「1」というのは「G<3」という条件に合うため、{}内の処理が実行される。
そしてまた内側の「for(int R=0; R<4; R++)」が初期値「int R=0」から処理が行われるのである。
Aの値は「5」に戻らないよ。
Aはこの時点で「25」。
「プログラムは順番に処理される」というポイントが抑えられていれば大丈夫だと思う。
それが以下のコード。
int [][] Nijigen= new int[3][4];
int A=5;
for(int G =0; G<3; G++){
for(int R=0; R<4; R++){
Nijigen[G][R]=A;
A += 5;
}
}
今見るとちょっと簡単に見えるんじゃないかな?
全てのループが終わると、箱の中は以下の数字が入っているということになる。
これらの数字を画面に表示したいときも2つのforループを使って表すことができる。
上の式の下に下記を付け加えるだけで大丈夫。
for( int G =0; G<3; G++){
for( int R=0; R<4; R++){
System.out.println(G +”,”+ R+”=”+ Nijigen[G][R]);
}
}
実行すると以下の結果が表示される。
0,0=5
0,1=10
0,2=15
0,3=20
1,0=25
1,1=30
1,2=35
1,3=40
2,0=45
2,1=50
2,2=55
2,3=60
まとめ
ちょっと長々としちゃったけど、一つ一つ見ていけば、今までやってきたことも組み合わさっているだけのものだということがわかった。
別々だと簡単に見えちゃうけど、複合してくると複雑に見える。
一目見て「うわー」って思っても、紐解いていけばシンプル。
慣れが大事なんだろうなと思った次第であります。
コメント