kotaro-ktr
@kotaro-ktr (Kotaro Tanaka)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

while文で四角形がうまく出力できません

Q&A

Closed

解決したいこと

while文を用いて四角形を出力してみたいと思い、phpで記述してみました。
試してみたところうまく出力されませんでした。
1行目もしくはn行目はn個#を描き、それ以外は1列目とn列目のみ#を描くというプログラムを作りたいと思っています。

image.png

↑の画像のシャープ(#)が5×5の四角形になるようにwhile文で表現したいと考えております。

該当するソースコード

<?php
  $n = 5;
  $i = 1; //行数
  $j = 1; //列数

  while ($i <= $n) {
    while ($j <= $n) {
      if ($i == 1 || $i == $n){
        echo "#";
      }
      else{ 
        if ($j == 1 || $j == $n){
          echo "#";
        }
        else{
          echo " ";
        }
      }
      $j ++;
    }
    $i ++;
    echo "</br>";
  }
 

`

考えたこと

デベロッパツールを使いどうなっているか確認したところ、改行(<br)は5回分できてそうだったので、iやjの値が2・3・4...となる際に全て空白で表記されてしまっているのかと思いました。
ただ、順番に処理を見て行ってみてもあまりわからなかったので、教えていただけますと助かります。

0

1Answer

これを実行した結果は#####</br></br></br></br></br>です。
空白は入っていません。

何が起きているかというと、内側のwhileは1行目分しか実行されていません。
最初の#5個を表示して2行目に入る段階で行数を表す$iは2、列数を表す$jは6になっています。
$jは5以下」という条件に当てはまらないので、以降は内側のwhileは実行されません。

whileでこれを行うには、列数を表す$jを1に戻さなくてはいけません。

1Like

Comments

  1. @kotaro-ktr

    Questioner

    ありがとうございます!
    以下のように修正したところ無事に四角形を描くことができました。
    <?php
    $n = 7;
    $i = 1; //行数
    $j = 1; //列数

    while ($i <= $n) {
    while ($j <= $n) {
    if ($i == 1 || $i == $n){
    echo "#";
    }
    else{
    if ($j == 1 || $j == $n){
    echo "#";
    }
    else{
    echo " ";
    }
    }
    $j ++;
    }
    $i ++;
    echo "</br>";
    $j = 1; //←アドバイス通り$jを1に戻してみました。
    }



    ただ解決したのですが、

    ①最初の#を5個表示して2行目に入る際のjの値が5→6になる理由がいまいちピンときません。(jがそもそも5になった理由も...)

    ②少し戻ってしまうのですが、1行目かn行目は#をn回分描画する処理は、結局wihle文の中のどの処理で行われたのでしょうか。

    ③上のコードで解決したものの、最後の$j=1にしたことで、3行目・4行目に行く際も$jは1に戻ってしまいうまく描けないのではないでしょうか。(実際うまく機能しているのですが...もやもやしております。)

    恐縮ですが、ご教示いただけますと大変ありがたいです。
    (うまく文が表示されず見づらく申し訳ございません。)

  2. > ①最初の#を5個表示して2行目に入る際のjの値が5→6になる理由がいまいちピンときません。(jがそもそも5になった理由も...)

    正確にいうと、6になったことにより`$j <= $n`が偽になり1行目の処理が終わる、となります。
    whileの最後にある`$j++`は`$j = $j + 1`と同じで`$j`の値が1ずつ増えます。
    5列目の処理の最後に5->6になります。


    > ②少し戻ってしまうのですが、1行目かn行目は#をn回分描画する処理は、結局wihle文の中のどの処理で行われたのでしょうか。

    #を表示していたのはこの部分です。

    if ($i == 1 || $i == $n){
    echo "#";
    }

    > ③上のコードで解決したものの、最後の$j=1にしたことで、3行目・4行目に行く際も$jは1に戻ってしまいうまく描けないのではないでしょうか。(実際うまく機能しているのですが...もやもやしております。)

    `$i`と`$j`の動きを表現したものです。(数値は$i-$j)
    列(→)の動きが内側のwhileで、行(↓)の動きが外側のwhileです。
    最初は1-1から1-5に進み、`$j`が6になった段階で2行目に移ります。
    この時に`$j`を1を戻すことにより内側のwhileの条件が真となるので、2-1から2-5まで進んでいきます。
    この繰り返しです。

    |1-1|1-2|1-3|1-4|1-5|</br>
    |2-1|2-2|2-3|2-4|2-5|</br>
    |3-1|3-2|3-3|3-4|3-5|</br>
    |4-1|4-2|4-3|4-4|4-5|</br>
    |5-1|5-2|5-3|5-4|5-5|</br>

  3. @kotaro-ktr

    Questioner

    かなり分かりやすくご説明いただきありがとうございました!

    $iが2〜4の場合は
    if ($i == 1 || $i == $n)
    が偽となるため、列である$jの

    if ($j == 1 || $j == $n){
    echo "#";
    }
    else{
    echo " ";
    }

    がn回実行(nを超えたなと判断されるまで)される。そしてまた$jは1に戻り、$i(行)を1増やして最初に戻るという二重ループということですね!

    ありがとうございました😭

Your answer might help someone💌