Java中的数字金字塔

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();
        }
    }
}

请问有人能帮我理解这个吗? 以下是我已经理解的内容: 外层循环从1到7递增,同时内层循环j从1到x-i递增,对于外层循环第一次迭代而言,x-i为6,然后依次为5、4等等。因此,金字塔的左侧只是一个倒置的空白三角形。

我无法理解另外两个嵌套循环以及print语句中奇怪的if-else部分。

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

现在是观察的时候。 通过观察,我们可以得出以下想法。 想法:金字塔是两个三角形的结构。 结论:编写该金字塔的一半更容易。因此,让我们重新表述我们的问题。 Q2:如何编写看起来像三角形的序列号? 这真的很简单,我们只需要两个循环,第一个循环负责列,另一个循环负责行。
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 

我们应该修改您的代码,使其更加适合。在计算机世界中,通常操作从零开始而不是从一开始。
   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));
}

那段代码表明,我们每一步只设置一个值。具体如下所示。
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] [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ]

完成九个步骤后,我们将用数字填充整个数组。

我们还缺少的是屏幕上的结果。为此,我们应该在每个步骤中打印整个数组。首先,我们应该从左到右打印它,然后从右到左打印。

执行这个神奇操作的代码应该如下所示

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("");
    }
}

5
让我们一步一步地走。正如你已经发现的那样,x是代表金字塔高度的变量。 然后,正如你也正确发现的那样,第一个循环创建当前数字行的缩进。 第二个循环现在将写入数字的左侧部分,但如果我没弄错的话,它将从最高数字开始递减,然后第三个循环将再次增加数字,从而创建略有不同的金字塔形状。 现在,看起来奇怪的if-else部分,正如你所称呼的那样,是三元条件运算符,它们在此代码中唯一的作用是通过省略数字的前导空格来修复金字塔包含数字>=10时的数字间距。 :)

4

这是一份作业。通过自己动手完成,而不是盲目地抄袭别人的作品,你会学到更多。

从一个类似但更简单的问题开始:

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

你能打印那个三角形吗?编写自己的代码并测试其正确性。

现在将你的代码修改为打印数字而不是星号:

    1
   123
  12345
 1234567

你能打印那个三角形吗?请编写自己的代码并测试其正确性。

现在再次修改您的代码以解决最终问题。通常,通过先解决类似但较简单的问题来解决困难问题会更容易。通过重用代码,您可以从解决简单问题的解决方案构建到解决更复杂问题的解决方案。

当然,可以融合发现的代码的思想和技术,但不要盲目地复制它。使用他们代码的优点编写您自己的代码。


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 

0

思考两种模式。

第一种模式,打印左右。

第二种模式,打印每行并检查与打印起点之间的间隙。

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 

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("");
    }
}

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);
}

欢迎来到 Stack Overflow。请阅读 [答案]。请注意,其他几个回答这个将近 9 年的问题的答案大部分时间都在 _解释_。Stack Overflow 是关于学习的,而不是提供代码片段供盲目复制粘贴。 - Chris

0
在这里,还有另外两个嵌套循环:
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为真,则k的值将不带空格显示。如果条件为假,则会带有空格地显示k的值。

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

0

想象一个以上部中点为原点的坐标平面:

class CoordinatePlane {
    public static void main(String[] args) {
        int n = 8;
        // vertical axis
        for (int i = 0; i <= n; i++) {
            // horizontal axis
            for (int j = 1 - n; j <= n - 1; j++)
                // print axes, otherwise whitespaces
                System.out.printf("%2s", i == 0 ? j : j == 0 ? i : "");
            // print a new line
            System.out.println();
        }
    }
}

坐标平面:

-7-6-5-4-3-2-1 0 1 2 3 4 5 6 7
               1              
               2              
               3              
               4              
               5              
               6              
               7              
               8              

稍加修改,您就可以得到一个数字金字塔:

class Pyramid {
    public static void main(String[] args) {
        int n = 8;
        // vertical axis
        for (int i = 1; i <= n; i++) {
            // horizontal axis
            for (int j = 1 - n; j <= n - 1; j++) {
                // absolute value - the distance from the zero point
                int jAbs = Math.abs(j);
                // print numbers, otherwise whitespaces
                System.out.printf("%2s", jAbs < i ? n - jAbs : "");
            }
            // print a new line
            System.out.println();
        }
    }
}

数字金字塔:

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

另请参阅: 如何获得以下格式化输出?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接