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,对于外循环的第一次迭代,它是 6,然后是 5 ...等等。 . 所以基本上金字塔的左边只是一个倒三角形的空白。

我无法弄清楚其他两个嵌套循环中发生了什么以及打印语句中看起来很奇怪的 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

现在是观察的时候了。

从那个观察我们可以想出以下想法。

想法:金字塔是两个三角形的结构。

结论:写出那个金字塔的一半比较容易。因此,让我们重新表述酸问题。

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("");
    }
}
于 2012-09-04T17:41:21.797 回答
5

让我们一步一步来。正如您已经知道的那样,x 是一个表示金字塔高度的变量。

然后,正如您也正确发现的那样,第一个循环创建当前数字行的缩进

第二个循环现在将写入数字的左半部分,但如果我做对了,它将从最高数字开始并递减,然后第三个循环将再次增加数字,创建一个与您的金字塔略有不同的金字塔'正在寻找。

现在,看起来很奇怪的 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

在其他两个嵌套循环中:

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 的值带空格地显示。

于 2012-09-09T19:57:43.617 回答
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
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

想想两种模式。

第一个图案,左右打印。

第二个 Pattern ,打印每一行并检查打印起点的间隙。

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 回答
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

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

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

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

于 2021-07-13T05:00:18.767 回答