二重ループ
並べたはずが、全部つながって 1 行になる
* を 6 個並べるだけなら for を 1 本書けば終わります。ところが「1 行目は *、2 行目は **」のように行に分かれた形を作ろうとすると、1 本の for では手が足りません。出てくるのは ****** という 1 本の棒です。
行を作るには、ループをもう 1 段重ねます。外側で行を、内側でその行の中身を担当させる。これが二重ループです。
外側が 1 回進むあいだに、内側は最初から最後まで回る
Java
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
System.out.print(i + "-" + j + " ");
}
}出てくるのは次の並びです。
プレーンテキスト
0-0 0-1 0-2 0-3 1-0 1-1 1-2 1-3 2-0 2-1 2-2 2-3外側の i が 0 から 1 に進むためには、内側の j が 0 から 3 まで走り切らなければなりません。だから本体は 3 回でも 4 回でもなく、3 かける 4 で 12 回動きます。外側が n 回、内側も n 回なら n かける n 回です。ここを取り違えると、思ったより桁違いに重い処理を書いてしまいます。
慣習として、外側のカウンタは i、内側は j と名付けます。内側で i++ と書いてしまう取り違えは定番の事故なので、どちらがどちらを担当するかを決めてから書き始めてください。
改行を置ける場所は 1 か所しかない
1 行ぶんの * を並べ終えるのは、内側のループを抜けた瞬間です。つまり改行は内側ループの外、外側ループの中に置きます。内側の中に入れると 1 文字ごとに改行され、縦に細長い出力になります。
文字列を少しずつ組み立てるときは StringBuilder を使うのが Java の作法です。
Java
StringBuilder buf = new StringBuilder();
buf.append("A");
buf.append("-");
String result = buf.toString();String を + でつないでも動きますが、ループの中で連結すると毎周ごとに新しい文字列が作り直されます。
やってみよう
Solution.pyramid(int n) を完成させましょう。pyramid(3) は "*\n**\n***" を返します。
考えるところは 2 つです。ひとつは内側のループを何回まわすかです。行によって * の数が変わるので、内側の上限は外側のカウンタに連動させます。
もうひとつは末尾の改行です。期待値は "*\n**\n***" であって "*\n**\n***\n" ではありません。最後の行だけ改行を飛ばすか、改行を行の先頭に置いて 1 行目だけ飛ばすか、どちらかの手当てが要ります。目に見えない 1 文字が残っているだけでテストは落ちます。
要件
- クラス名は
Solution、メソッド名はpyramid、引数はint n1 つ、戻り値の型はStringにすること - 外側ループで行、内側ループで
*の個数を回す二重ループで組み立てること - 各行は
\nで連結し、末尾には余計な改行を付けないこと (pyramid(3)の期待値は"*\n**\n***")
入出力例
pyramid(3) → "*
**
***"
pyramid(5) → "*
**
***
****
*****"
pyramid(1) → "*"