多重ループの要素について




皆さんこんにちは、プロクラスの野間です。
プログラムの「繰り返し処理」でシングルループは出来るけど、多重ループで詰まる方がおられるようですので、
今回はプログラムのループについて、主に多重ループを見据えた「シングルループでも多重ループでも考え方は全て同じ」である事をお話ししたいと思います。

■ループは次の2つの処理で出来ています
①主処理
②次の準備
ここではこの2つの観点に着目してマイクラ風に繰り返しを説明します。
タートルがブロックを置くだけの簡単処理で行きたいと思います。

①主処理
繰り返しで実際にやりたい処理の事です。
今回の例ではブロックを置いて線を引いたり、床を作ったりするので、
主処理は「タートルの下にブロックを置く」になります。

②次の準備
主処理を行った後、繰り返すための準備処理です。
今回の例では、ブロックを置いた後、「次に置きたい位置に移動する」事になります。

動きのイメージとしては
置く、移動する、置く、移動する、置く、移動する・・・

如何でしょうか。文章で纏めてみると、どうみても同じことを繰り返しているように見えますよね。
まずは直線にブロックを並べるシングルループを考えてみます。

■ブロックを直線に並べる(シングルループ)
まずはブロックを直線に並べる例を基準に見てみます。

一列に並べる繰り返しの場合、①主処理は「ブロックを置く」になります。
置いてしまうと、もう下にはおけなくなるので、別の場所に移動しないといけません。
ですので②次の準備は一歩移動になります。

①ブロックを置く

②一歩移動

手動で続けてみると・・・







一直線にブロックが並べられていきます。
上記の手順を見ればわかると思いますが、単純に①と②を繰り返しているだけです。
自力でプログラムを書くのは面倒ですので、これを繰り返すように指示するコマンドが繰り返しコマンドになります。
単純に①と②を繰り返しで囲むだけになります。
・5回繰り返しはじめ
・ ①
・ ②
・繰り返し終わり

5回繰り返したら以下のようになるのがわかるでしょうか。
動きをイメージしてください。

この様に繰り返しの基本は「主処理」と「次の準備」を繰り返しコマンドで囲む事になります。
「繰り返しはじめ」と「繰り返し終わり」はついになるものなので、括弧をイメージしてください。
「繰り返しはじめ」があると必ず同じ数だけ「繰り返し終わり」が必要になります。
括弧の数が一致しない事はありえません。

算数で「2+(5+1)+6-(3+4」とか無いのと同じです。

この①と②は逆でもOKなのですが、①②の順でプログラムを書くことが多いです。
これは「始める位置」が関係してくるためです。
「開始した位置に置く」と「開始後移動した位置に置く」とでは、差が出ます。
まずは①②の順で覚えるようにしましょう。

■二重ループ
さて、いよいよ多重ループです。
繰り返しは繰り返しの中に入れる事が出来ます。
「入れ子」と呼ばれるものになります。
ちなみに「入れ子」とはプログラム用語ではありません。
何かの中に何かが入るようになっているものの事を「入れ子」と言います。(入れ子構造)
有名なマトリョーシカ等も入れ子です。
算数の計算では「2+((5+1)+(6-3))」の感じです。

ここではループの中にループが入っている場合を多重ループと呼び、
ループが二つの場合は二重ループと呼びます。

今回はオーソドックスに正方形の形(5*5)にブロックを並べる事を考えます。
これも基本通りで「①主処理」と「②次の準備」の構成で出来ています。
今回の「①主処理」はシングルループで作った
「一直線にブロックを並べる」自体になります。
その後に「②次の準備」として「次の開始位置」に移動します。
今回の「次の位置」は「一歩移動」ではなく、結構動く必要があります。

移動は「1行目の開始位置の隣」に移動する必要があります・・・が、
ただ横に移動するだけだと次の位置に来てしまうので

このまま同じ処理を繰り返してしまうと、以下のようになります



・・・略・・・

動きをイメージしてください。

1列作成の真横に作りたいので、開始位置は次の位置になります。
最初の位置

次の位置

先ほどやりましたが、この位置から始めると・・・

こうなりました

ではこの位置から始めると・・・

こうなりますよね?

※わかり難いですが1行横にずれています

動きをイメージしてください。

ですので、1列置き終わった後に

次の開始位置である位置に移動して・・・

ここからスタートしたらどうなりますか?

この時、タートルの位置は「次の開始位置」なので、こうなっているはずですよ?

①主処理「1列作成」

②次の準備「次の開始位置に移動」

この2つの処理を5回繰り返すと・・・
・5回繰り返しはじめ
・ ①「1列作成」
・ ②「次の開始位置に移動」
・繰り返し終わり

次のようになるのはわかるでしょうか?

動きをイメージしてください。

終わった時、タートルは次の位置に来ているのがわかるかと思います。

手順を全て書くと・・・
・5回繰り返しはじめ
・ ①5回繰り返しはじめ
・ ブロックを置く
・ 一歩移動
・ 繰り返し終わり
・ ②「次の開始位置に移動」
・繰り返し終わり

入れ子になります。
元々の「1列作成」のプログラムが一切書き換わっていない点に注目してください。
「1列作成」そのまま丸々が主処理になります。
そして、「②次の準備」は「主処理終了後からどうするか」だけを考えればOKです。

この様にシングルループも二重ループも全く同じ考え方になります。
もちろん、この先の多重ループも全く同じ考え方です。

多重ループの考え方あるあるですが、入れ子ですので、「繰り返し終わり」は交差する事はありません。
あくまで「繰り返しはじめ」は「括弧はじめ」であり、「繰り返し終わり」は「括弧閉じる」です。
算数の計算で、括弧を書く時、「括弧はじめ」と「繰り返し終わり」の対応で悩むことは無いですよね?
「繰り返しはじめ」と「繰り返し終わり」の対応も全く同じ考え方になります。
「インデント」をしっかりと付けると対応がわかりやすくなります。

■三重ループ
ではこれを更に繰り返しで囲って三重ループに挑戦です。
オーソドックスな例として立方体にします。
この考え方も基本通り
①主処理
②次の準備
です。

二重ループでやったプログラムをそのままが三重ループの「①主処理」です。
つまり、「②次の準備」は二重ループ終了後の位置から次の開始位置に移動すればOKです。
次の開始位置はここです。わかりますか?

この位置から始めるので

こうなります

ではこの位置から始めると

こうなるはずですよね?

となると「②次の準備」はこの位置から

「この位置に移動」する事になります

上に上がって横に5移動して、奥行に5移動する必要があります。

次の話は想像つきますか?(笑

この2つの処理を5回繰り返すと・・・
・5回繰り返しはじめ
・ ①「5列作成」
・ ②「次の開始位置に移動」
・繰り返し終わり

動きをイメージしてください。

二重ループの手順を展開します
・5回繰り返しはじめ
・ ①5回繰り返しはじめ
・ ①「1列作成」
・ ②「次の開始位置に移動」
・ 繰り返し終わり
・ ②「次の開始位置に移動」
・繰り返し終わり

シングルループの手順を展開します
・5回繰り返しはじめ
・ ①5回繰り返しはじめ
・ ①5回繰り返しはじめ
・ ①ブロックを置く
・ ②一歩移動
・ 繰り返し終わり
・ ②「次の開始位置に移動」
・ 繰り返し終わり
・ ②「次の開始位置に移動」
・繰り返し終わり

幾重に入れ子を増やしても考え方は全て同じ
①主処理
②次の準備
を繰り返しコマンドで囲むだけになります。

そして、「②次の準備」は「①主処理」終了後に次の開始準備をどうするかだけを考える事になります。

一度に全てを捕えようとして、三重ループの手順を見ると頭がグルグルしてきますが、
①②の手順に当てはめて、しっかりと区切って手順を見るとそれほどではなくなってきます。

直線の手順
①ブロックを置く
②次の位置に移動
を繰り返す

面の手順
①直線配置
②次の位置に移動
を繰り返す

立体の手順
①面の配置
②次の位置に移動
を繰り返す

ループ数が1重だろうと、複数回だろうと、手順はかわりません。
今回は目に見えやすいようにブロックを置きましたが、別の何かに変わっても同じです。
まずは基準に慣れて、その後、別の何かに置き換えると覚えやすいかもしれません。

「考え方」「捉え方」は人それぞれですので、全ての人に伝わるような万能な説明は無いと思います。
今回は「全て同じ考え方です」の形の紹介をしてみました。
多重ループに行き詰まっている方の一助になれば幸いです。