1

ピラミッド セットのレイアウトを持っていますが、次のいくつかの数字をどのように組み合わせたり、数学的に取得したりするかがわかりません。私が必要とするのは:

       1
     1 2 1
    1 3 3 1
   1 4 6 4 1
 1 5 10 10 5 1
1 6 15 20 15 6 1

現在の私のコードは次のとおりです。

int x = 7;
for (int i =1; i<=x; i++) {
    for (int j =1; j<=x-i; j++) {
        System.out.print("  ");
    }
    for (int k=1; k<=i;k++) {
        System.out.printf("%2d",k);
    }
    for(int k=i-1; k>=1;k--) {
        System.out.printf("%2d",k);
    }
    System.out.println(" ");
}

しかし、私の出力は次のようになります。

            1
          1 2 1
        1 2 3 2 1
      1 2 3 4 3 2 1
    1 2 3 4 5 4 3 2 1
  1 2 3 4 5 6 5 4 3 2 1
1 2 3 4 5 6 7 6 5 4 3 2 1

これがおかしくなったらごめんなさい。これは、このサイトで初めての質問です。コードを変更して他のピラミッドを取得するにはどうすればよいですか?

4

1 に答える 1

3

まず、パスカルの三角形を計算しようとしていると思います。あなたが書いたとき、望ましい出力は次のとおりでした。

       1
     1 2 1
    1 3 3 1
   1 4 6 4 1
 1 5 10 10 5 1
1 6 15 20 15 6 1

あなたは実際に意味します:

       1
      1 1
     1 2 1
    1 3 3 1
   1 4 6 4 1
 1 5 10 10 5 1
1 6 15 20 15 6 1

そうしないとあまり意味がないからです。

わずかなエラーがあり、2 番目の三角形が必要な三角形であると仮定すると、それはパスカルの三角形です。パスカルの三角形を計算するためのルールは、上と左の数と上と右の数を足して新しい値を求めることです。

パスカルトライアングル

画像クレジット Hersfold

これを行う再帰関数は非常に簡単に作成できます。再帰関数を使用する場合、ガードと基本ケースを記述してから再帰することをお勧めします。これは次のようになります。

private static int calculatePascalNumber(int row, int column)
{
    if (row < 1 || column < 1 || column > row) {
        return 0;
    } else if (column == 1 || row == column) {
        return 1;
    } else {
        return calculatePascalNumber(row - 1, column - 1) + 
                    calculatePascalNumber(row - 1, column);
    }
}

これらは、この関数のルールです

  • 行または列が 1 未満の場合、または列が行よりも広い場合、これらは三角形の外側の点であり、0 を返す必要があります
  • 列が最後の列の 1 つにある場合 (列が 1 に等しいか、行と列が等しい)、1 を返します。
  • それ以外の場合は、上記の 2 つの数値を左右に追加します

次に、次のようなコード内でこの関数を呼び出すことができます

int x = 7;
for (int row = 1; row <= x; row++) {

    for (int j =1; j<=x-row; j++) {
        if (j % 2 == 0) {
            System.out.print("  ");
        } else {
            System.out.print(" ");
        }
    }

    for (int column=1; column<=row;column++) {
        System.out.printf(" %2d", calculatePascalNumber(row, column));
    }

    System.out.println(" ");
}

書式設定のために少し修正しました。さらに作業を進めたい場合は、出力の書式設定を確認することをお勧めします。

最後に、注目すべきはパフォーマンスです。大きな三角形の値を計算するためにこれを実行したい場合、再帰呼び出しの数が増え始め、この関数の動作が非常に遅くなります。これを解決する方法として考えられるのは、calculatePascalNumber の呼び出しの結果をキャッシュして、パラメーターを指定して呼び出されたときに、すべての計算を複数回実行するのではなく、既に計算されているハッシュマップ/配列から値を返すようにすることです。

より大きな三角形でこれを高速化する別のオプションは、この関数を使用して行を単独で計算することです。これにより、次のような calculatePascalNumber のコードが生成される可能性があります。

private static int calculatePascalNumber(int row, int column)
{
    if (row < 0 || column < 0 || column > row) {
        return 0;
    } else if (column == 1) {
        return 1;
    } else {
        return (calculatePascalNumber(row, column - 1) 
                  * (row + 1 - column)) / (column - 1); 
    }
}

しかし、効率化によって得たものは、明晰さによって失われます。

于 2014-11-10T10:28:59.363 に答える