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…

したがって、各行にrx 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ループのみで構成される別の方法があります。ApacheCommonsLang3ライブラリを使用します。

前の例で行ったように、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();
}

または、次の方法で巧妙なトリックを行うことができます substring()メソッド。

上記の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()メソッドの正しい式を見つけるだけです。

ここで、完全な例を見てみましょう。

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)があります。 複雑さ。 したがって、全体的な時間計算量は同じままです。

最後に、補助スペースについて話している場合、すべての例で、複雑さがStringBuilder変数にとどまっていることがすぐにわかります。 三角形全体を結果変数に追加することにより、O(N ^ 2)未満の複雑さを持つことはできません。

もちろん、文字を直接印刷した場合、最初の2つの例では一定のスペースの複雑さがあります。 ただし、3番目の例ではヘルパー文字列を使用しており、スペースの複雑さは O(N)になります。

5. 結論

このチュートリアルでは、Javaで2つの一般的なタイプの三角形を印刷する方法を学びました。

最初に、直角三角形を調べました。これは、Javaで印刷できる最も単純なタイプの三角形です。次に、二等辺三角形を作成する2つの方法を調べました。最初のものはforループのみを使用し、もう1つは StringUtils.repeat()および String.substring()メソッドを利用して私たちを助けます書くコードを減らします。

最後に、各例の時間と空間の複雑さを分析しました。

いつものように、すべての例はGitHubにあります。