6

次のようなピラミッドを Java で印刷しようとしています。

                9
              8 9 8
            7 8 9 8 7
          6 7 8 9 8 7 6
        5 6 7 8 9 8 7 6 5
      4 5 6 7 8 9 8 7 6 5 4
    3 4 5 6 7 8 9 8 7 6 5 4 3
  2 3 4 5 6 7 8 9 8 7 6 5 4 3 2
1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1

私はインターネットでこれを解決する方法を探していましたが、これに出くわしました:

class Pyramid {
    public static void main(String[] args) {
        int x = 7;
        for (int i = 1; i <= x; i++) {
            for (int j = 1; j <= x - i; j++)
                System.out.print("   ");
            for (int k = i; k >= 1; k--)
                System.out.print((k >= 10) ? +k : "  " + k);
            for (int k = 2; k <= i; k++)
                System.out.print((k >= 10) ? +k : "  " + k);
            System.out.println();
        }
    }
}

誰でもこれを理解するのを手伝ってもらえますか? ここで私が理解したこと: - 外側のループは 7 までインクリメントし、同時に内側の j ループは x - i までインクリメントします。 . したがって、基本的にピラミッドの左側は空白の逆三角形です。

ネストされた他の 2 つのループと、print ステートメント内の奇妙な if - else パーツで何が起こっているのかを理解するのに苦労しています。

4

10 に答える 10

10

タスクは本当に複雑に見えるので、実際には簡単です。最初は難しく見えるかもしれません。結果に導くルートではなく、最終結果を考えているからです。

コーディングの古いルールを使用できるように変更するには、分割統治. このアプローチは、複雑な問題の類似点を見つけて、主な問題を実行可能な単純なタスクに減らすことを教えてくれます。言い換えれば、私たちは大きな問題をいくつかの小さな問題に分割します。これは非常に簡単に解決でき、最後に小さな結果を大きな問題に結合します。

だからあなたの問題から始めないでください。

Q1: 数字のピラミッドを印刷するには?

それがわからないので、他のことに焦点を当てましょう。

観察を改善するために、背景の詳細​​を追加できます

  1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
0 _ _ _ _ _ _ _ _ 9 _ _ _ _ _ _ _ _
1 _ _ _ _ _ _ _ 8 9 8 _ _ _ _ _ _ _
2 _ _ _ _ _ _ 7 8 9 8 7 _ _ _ _ _ _
3 _ _ _ _ _ 6 7 8 9 8 7 6 _ _ _ _ _
4 _ _ _ _ 5 6 7 8 9 8 7 6 5 _ _ _ _
5 _ _ _ 4 5 6 7 8 9 8 7 6 5 4 _ _ _
6 _ _ 3 4 5 6 7 8 9 8 7 6 5 4 3 _ _
7 _ 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 _
8 1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1

今こそ観察の時です。

その観察から、次のアイデアを思いつくことができます。

アイデア: ピラミッドは 2 つの三角形の構成です。

結論: そのピラミッドの半分を書く方が簡単です。それでは、酸っぱい問題を言い換えましょう。

Q2: 三角に見える連番の書き方は?

これは本当に簡単です。最初のループが列を担当し、行を担当するために必要なのは 2 つのループだけです。

for (int column = 1; column <= 9; column++) {
    for (int row = 1; row <= 9; row++) {
        // Observe what will happen if
        // we use == or <= or > or <>
        if (column ## row) {
            System.out.print(row);
        } else {
            System.out.print(" ");
        }
    }
    System.out.println(' ');
}

最初のタスクを完了すると、画面に正方形、三角形、数字の行を印刷できるようになります。

したがって、次のような三角形を印刷する方法がわかっている場合:

   r
c    1 2 3 4 5 6 7 8 9 
   1 _ _ _ _ _ _ _ _ 9 
   2 _ _ _ _ _ _ _ 8 9 
   3 _ _ _ _ _ _ 7 8 9 
   4 _ _ _ _ _ 6 7 8 9 
   5 _ _ _ _ 5 6 7 8 9 
   6 _ _ _ 4 5 6 7 8 9 
   7 _ _ 3 4 5 6 7 8 9 
   8 _ 2 3 4 5 6 7 8 9 
   9 1 2 3 4 5 6 7 8 9 

通常、コンピューターの世界での操作は 1 つではなくゼロから始まります。

   r
c    0 1 2 3 4 5 6 7 8  
   0 _ _ _ _ _ _ _ _ 9 
   1 _ _ _ _ _ _ _ 8 9 
   2 _ _ _ _ _ _ 7 8 9 
   3 _ _ _ _ _ 6 7 8 9 
   4 _ _ _ _ 5 6 7 8 9 
   5 _ _ _ 4 5 6 7 8 9 
   6 _ _ 3 4 5 6 7 8 9 
   7 _ 2 3 4 5 6 7 8 9 
   8 1 2 3 4 5 6 7 8 9 

あなたがそれで成功したら、私たちはちょっと立ち止まって考えます。

行ごとにこれらすべての操作を繰り返さなければならないのはなぜですか? 値をどこかに置くことができれば、それらを考えて計算する必要はなくなり、結果全体を画面に書き込むことだけに集中できます。

この問題の解決策は、配列と動的計画法として知られるアプローチの概念です。このアプローチでは、将来の操作に使用されることをどこかに記憶しようとします。

したがって、ワームアップとして、それらを印刷する代わりに、配列に番号を割り当てるだけにしましょう。

[ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [9]
[ ] [ ] [ ] [ ] [ ] [ ] [ ] [8] [9]
[ ] [ ] [ ] [ ] [ ] [ ] [7] [8] [9]
[ ] [ ] [ ] [ ] [ ] [6] [7] [8] [9]
[ ] [ ] [ ] [ ] [5] [6] [7] [8] [9]
[ ] [ ] [ ] [4] [5] [6] [7] [8] [9]
[ ] [ ] [3] [4] [5] [6] [7] [8] [9]
[ ] [2] [3] [4] [5] [6] [7] [8] [9]
[1] [2] [3] [4] [5] [6] [7] [8] [9]

で、次のようなコードを考え出す必要があります

int[] array = new int[9];

for (int column = array.length; column > 0; column--) {
    for (int row = 0; row <= array.length; row++) {
        if (column == row) {
            array[row - 1] = column;
        }
    }
    System.out.println(Arrays.toString(array));
}

そのコードから明らかなことは、各ステップで 1 つの値のみを設定するということです。それを以下に示します

9  [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [9] - Step one we put nine
8  [ ] [ ] [ ] [ ] [ ] [ ] [ ] [8] [ ] - Step two we put eight
7  [ ] [ ] [ ] [ ] [ ] [ ] [7] [ ] [ ]
6  [ ] [ ] [ ] [ ] [ ] [6] [ ] [ ] [ ]
5  [ ] [ ] [ ] [ ] [5] [ ] [ ] [ ] [ ]
4  [ ] [ ] [ ] [4] [ ] [ ] [ ] [ ] [ ]
3  [ ] [ ] [3] [ ] [ ] [ ] [ ] [ ] [ ]
2  [ ] [2] [ ] [ ] [ ] [ ] [ ] [ ] [ ]
1  [1] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ]

9 つの手順の後、配列全体に数値を入力します。

まだ欠けているのは、画面上の結果です。そのためには、各ステップで配列全体を出力する必要があります。最初に左から右に印刷し、その後フロントエンドから先頭に印刷する必要があります。

そして、魔法を行うコードは次のようになります

public static void pyramide(int levels) {
    int[] tab = new int[levels];
    for (int row = tab.length; row > 0; row--) {
        tab[row - 1] = row;
        //Print left
        for (int i = 0; i < tab.length; i++) {
            if (tab[i] != 0) {
                System.out.print(tab[i]);
            } else {
                System.out.print(' ');
            }
        }
        //Print right
        for (int i = tab.length - 2; i >= row - 1; i--) {
            if (tab[i] != 0) {
                System.out.print(tab[i]);
            }
        }
        System.out.println("");
    }
}
于 2012-09-04T17:41:21.797 に答える
5

このステップを段階的に見ていきましょう。すでに理解しているように、xはピラミッドの高さを表す変数です。

次に、あなたも正しく知っているように、最初のループは現在の数字の行のインデントを作成します

2番目のループは数値の左半分を書き込みますが、正しく理解すると、最大の数値から開始してデクリメントし、3番目のループは再び数値をインクリメントして、あなたとは少し異なるピラミッドを作成します探しています。

さて、あなたが呼んでいる奇妙な見た目のif-elseパーツは、三項条件演算子であり、このコードでそれらが果たす唯一の目的は、ピラミッドに10以上の数値が含まれている場合に数値の間隔を修正することです。番号の先頭の空白。:)

于 2012-09-04T14:46:58.227 に答える
4

これは宿題です。他人の作品をやみくもにコピーするのではなく、自分でやることでより多くを学ぶことができます。

同様の、しかしより単純な問題から始めます。

    *
   ***
  *****
 *******

その三角形を印刷できますか?独自のコードを作成し、正しく動作することをテストします。

アスタリスクの代わりに数字を出力するようにコードを変更します。

    1
   123
  12345
 1234567

その三角形を印刷できますか?独自のコードを作成し、正しく動作することをテストします。

コードを再度変更して、最終的な問題を解決します。難しい問題に取り組むには、似ているが簡単な問題を最初に解決する方が簡単な場合がよくあります。コードを再利用することで、単純な問題の解決策から、より複雑な問題の解決策を構築できます。

見つけたコードのアイデアやテクニックをぜひ取り入れてください。ただし、むやみにコピーするだけではいけません。コードの良い点を使用して独自のコードを記述します。

于 2012-09-04T14:57:09.440 に答える
1

さあ行こう

public class Pyramid {
    public static void main(String[] args) {
        int[] arry = new int[10];
        for (int i = 1; i <= 9; i++)
            arry[i] = i;
        int index = 0;
        for (int i = 9; i > 0; i--) {
            int loop = 1, tempLoop = 0;

            for (int k = 0; k < 9; k++) {
                if (k < (9 - index))
                    System.out.print(" ");
                else
                    System.out.print(arry[k] + " ");
            }

            for (int k = 9; k >= i && (tempLoop++) <= index; k--) {
                System.out.print(arry[k] + " ");
            }
            index++;
            System.out.println();
        }
    }
}

出力:

         9 
        8 9 8 
       7 8 9 8 7 
      6 7 8 9 8 7 6 
     5 6 7 8 9 8 7 6 5 
    4 5 6 7 8 9 8 7 6 5 4 
   3 4 5 6 7 8 9 8 7 6 5 4 3 
  2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 
 1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1 
于 2012-09-04T15:31:08.303 に答える
0

これをインタビューの潜在的な質問と見なし、Java 8 のストリーム メソッドを使用して実装を試みたいと考えました。以下の解決策:

import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

public class App {
    public static void main(String[] args) {
        int min = 1;
        int max = 9;
        List<List<String>> pyramid = new ArrayList<>();
        IntStream.iterate(max, i -> i - 1).limit(max)
            .forEach(s -> {
                List<String> pyramidRow = new ArrayList<>();
                IntStream.rangeClosed(min, max)
                    .forEach(j -> {
                        if (j < s) pyramidRow.add(" ");
                        else pyramidRow.add(String.valueOf(j));
                    });
                IntStream.iterate(max - 1, i -> i - 1).limit(max - 1)
                    .forEach(j -> {
                        if (j < s) pyramidRow.add(" ");
                        else pyramidRow.add(String.valueOf(j));
                    });
                pyramid.add(pyramidRow);
            });
        pyramid.stream()
            .forEach(pyra -> {
                pyra.forEach(System.out::print);
                System.out.println();
            });
    }
}

出力:

        9        
       898       
      78987      
     6789876     
    567898765    
   45678987654   
  3456789876543  
 234567898765432 
12345678987654321
于 2016-03-28T19:46:12.920 に答える
0

他の 2 つのネストされたループでは、次のようになります。

for (int k = i; k >= 1; k--)
System.out.print((k >= 10) ?+ k : "  " + k);

for (int k = 2; k <=i; k++)
System.out.print((k >= 10) ?+ k : "  " + k);

条件k>=10が true の場合、k の値はスペースなしで表示されます。false の場合、k の値はスペースありで表示されます。

于 2012-09-09T19:57:43.617 に答える
0
for (int i = length - 1; i >= 1; i--) {
    String front = "";
    String back = "";
    int space = (length - i) - 1;
    while (space >= 0) {
        System.out.print(" ");
        space--;
    }
    for (int j = i; j != 0; j--) {
        front = j + front;
        if (j != i) {
            back = back + j;
        }
    }
    System.out.println(front + back);
}
于 2013-07-10T05:52:48.763 に答える
0
public class PrintInterviewPyramid {
    public static void main(String[] args) {
        int n = 8;
        for (int i = 1; i < n; i = i + 2) {
            for (int j = 1; j < i + 1; j++) {
                System.out.println(" " + j);
            }
        }
        System.out.println("");
    }
}
于 2013-01-29T09:10:24.763 に答える
0

2パターン考えます。

最初のパターン、左右に印刷します。

2 番目のパターンでは、すべての行を印刷し、印刷開始点とのギャップを確認します。

public class NumberPyramid {
    public static void main(String[] args) {
        int part = 2;
        int stage = 5; // set tree stage.
        if (part == 2) {
            int cnt = 0;
            // thinking two part.
            for (int i = stage; i > 0; i--) {
                for (int j = 1; j <= stage; j++) {
                    if (stage - j <= cnt) {
                        System.out.print(j + " ");
                    } else {
                        System.out.print("  ");
                    }
                }
                for (int k = stage; k > 0; k--) {
                    if (k != stage) {
                        if (stage - cnt <= k) {
                            System.out.print(k + " ");
                        } else {
                            System.out.print("  ");
                        }
                    }
                }
                System.out.println("");
                cnt++;
            }
        } else if (part == 1) {// think whole lines.
            int gap = 0;
            for (int j = 0; j < stage; j++) {
                for (int i = 1; i <= stage * 2; i++) {
                    if (Math.abs(i - stage) <= gap) {
                        System.out.print(stage - gap + " ");
                    } else
                        System.out.print("  ");
                }
                System.out.println("");
                gap++;
            }
        }
    }
}

出力:

        5         
      4 5 4       
    3 4 5 4 3     
  2 3 4 5 4 3 2   
1 2 3 4 5 4 3 2 1 
于 2015-06-14T01:03:21.407 に答える