Javaでforループを使用して三角形を作成する

1. 前書き

このチュートリアルでは、Javaで三角形を印刷するいくつかの方法を検討します。
当然、三角形には多くの種類があります。 ここでは、*そのうちのいくつか、つまり直角三角形と二等辺三角形のみを調べます。*

2. 直角三角形の構築

直角三角形は、これから学習する三角形の最も単純なタイプです。 取得したい出力を簡単に見てみましょう。
*
**
***
****
*****
ここで、三角形は5つの行で構成されており、各行には現在の行番号と同じ数の星が付いています。 もちろん、この観察は一般化できます:* 1から_N_までの各行に対して、_r_星を印刷する必要があります。ここで、_r_は現在の行、_N_は行の総数です。*
そこで、2つの_for_ループを使用して三角形を作成しましょう。
public static String printARightTriangle(int N) {
    StringBuilder result = new StringBuilder();
    for (int r = 1; r <= N; r++) {
        for (int j = 1; j <= r; j++) {
            result.append("*");
        }
        result.append(System.lineSeparator());
    }
    return result.toString();
}

3. 二等辺三角形の作成

次に、二等辺三角形の形を見てみましょう。
    *
   ***
  *****
 *******
*********
この場合、何が見えますか? *星に加えて、各行にいくつかのスペースを印刷する必要があることに気づきました*。したがって、各行に印刷する必要があるスペースと星の数を把握する必要があります。 もちろん、スペースと星の数は現在の行に依存します。
最初に、最初の行に4つのスペースを印刷する必要があることがわかります。三角形を下って行くと、最後の行に3つのスペース、2つのスペース、1つのスペースが必要になります。 *一般的に、各行に_N – r_スペースを出力する必要があります*。
第二に、最初の例と比較して、奇数個の星が必要であることがわかります:1、3、5、7…
したがって、*各行に_r x 2 – 1_スターを印刷する必要があります*。

3.1. ネストされた_for_ループの使用

上記の観察に基づいて、2番目の例を作成しましょう。
public static String printAnIsoscelesTriangle(int N) {
    StringBuilder result = new StringBuilder();
    for (int r = 1; r <= N; r++) {
        for (int sp = 1; sp <= N - r; sp++) {
            result.append(" ");
        }
        for (int c = 1; c <= (r * 2) - 1; c++) {
            result.append("*");
        }
        result.append(System.lineSeparator());
    }
    return result.toString();
}

3.2. 単一の_for_ループを使用する

実際、**「単一の_for_ループのみで構成される」という別の方法があります。これはlink:/java-commons-lang-3[Apache Commons Lang 3 library]を使用します。**
前の例で行ったように、forループを使用して三角形の行を反復処理します。 次に、_StringUtils.repeat()_メソッドを使用して、各行に必要な文字を生成します。
public static String printAnIsoscelesTriangleUsingStringUtils(int N) {
    StringBuilder result = new StringBuilder();

    for (int r = 1; r <= N; r++) {
        result.append(StringUtils.repeat(' ', N - r));
        result.append(StringUtils.repeat('*', 2 * r - 1));
        result.append(System.lineSeparator());
    }
    return result.toString();
}
または、https://www.baeldung.com/java-substring [_substring()_ method]。*を使用して、巧妙なトリックを実行できます。
上記の_StringUtils.repeat()_メソッドを抽出してヘルパー文字列を作成し、それに_String.substring()_メソッドを適用できます。 *ヘルパー文字列は、三角形の行を印刷するために必要なスペースの最大数と星の最大数の連結です。*
前の例を見てみると、最初の行には最大数の_N – 1_スペースが必要であり、最後の行には最大数の_N x 2 – 1_スターが必要であることがわかります。
String helperString = StringUtils.repeat(' ', N - 1) + StringUtils.repeat('*', N * 2 - 1);
// for N = 10, helperString = "    *********"
たとえば、_N = 5_および_r = 3_の場合、_helperString_変数に含まれる*******を印刷する必要があります。 必要なことは、_substring()_ methodの正しい式を見つけることだけです。
それでは、完全な例を見てみましょう。
public static String printAnIsoscelesTriangleUsingSubstring(int N) {
    StringBuilder result = new StringBuilder();
    String helperString = StringUtils.repeat(' ', N - 1) + StringUtils.repeat('*', N * 2 - 1);

    for (int r = 0; r < N; r++) {
        result.append(helperString.substring(r, N + 2 * r));
        result.append(System.lineSeparator());
    }
    return result.toString();
}
同様に、もう少し作業するだけで、三角形を逆さまに印刷することができます。

4. 複雑

最初の例をもう一度見ると、それぞれ最大_N_ステップの外側のループと内側のループがあります。 *したがって、_O(N ^ 2)_の時間の複雑さがあります。ここで、_N_は三角形の行数です。*
2番目の例は似ています。唯一の違いは、2つの内部ループがあり、それらは順次であり、時間の複雑さを増さないことです。
ただし、3番目の例では、_N_ステップの_for_ループのみを使用します。 しかし、すべてのステップで、ヘルパーストリングで_StringUtils.repeat()_メソッドまたは_substring()_メソッドを呼び出しており、それぞれが_O(N)_の複雑さを持っています。 したがって、全体的な時間の複雑さは変わりません。
最後に、補助スペースについて話している場合、すべての例で、複雑さがlink:/java-string-builder-string-buffer[_StringBuilder_]変数にとどまっていることがすぐにわかります。 。 *三角形全体を_result_変数に追加することにより、_O(N ^ 2)_未満の複雑さを持つことはできません。*
もちろん、文字を直接印刷した場合、最初の2つの例のスペースは常に複雑になります。 ただし、3番目の例ではヘルパー文字列を使用し、スペースの複雑さは_O(N)_になります。

5. 結論

このチュートリアルでは、Javaで2つの一般的なタイプの三角形を印刷する方法を学びました。
最初に、* Javaで印刷できる最も単純なタイプの三角形である直角三角形を学習しました。* *二等辺三角形を作成する2つの方法を調べました。*最初の方法では、_for_ループともう1つは、_StringUtils.repeat()_および_String.substring()_メソッドを利用して、より少ないコードを記述できるようにします。
最後に、各例の時間と空間の複雑さを分析しました。
いつものように、すべての例はhttps://github.com/eugenp/tutorials/tree/master/algorithms-miscellaneous-3[GitHubで]にあります。