【问题标题】:How to draw an ASCII staircase with Java?如何用 Java 绘制一个 ASCII 楼梯?
【发布时间】:2021-01-28 09:06:56
【问题描述】:

我一直在尝试用 Java 完成这项工作。这是一件很复杂的事情,至少对我来说是这样。

Q1 编写一个简单的 Java 程序,打印楼梯或图形,如下所示:

                +---+
                |   |
            +---+---+
            |   |   |
        +---+---+---+
        |   |   |   |
    +---+---+---+---+
    |   |   |   |   |
+---+---+---+---+---+
|   |   |   |   |   |
+---+---+---+---+---+

我想出了一个解决方案,但它甚至还没有完成一半。这是我想出的代码

public class DrawStairs {
    public static final int HEIGHT = 5;
    public static final int TOTALHEIGHT = HEIGHT * 5;
    public static void main(String[] args) {
        //Main Outer Loop
        for (int i = 1; i <= HEIGHT; i++) {
            //Loop for the spaces before, then print the head
            for (int j = 1; j <= TOTALHEIGHT + (i * (-5)); j++) {
                System.out.print(" ");
            }
            printTop();
            //Loop for spaces after, then print asterisk
            for (int j = 1; j <= (i - 1); j++) {
                System.out.print("---+");
            }
            System.out.println(" ");
            //Loop for the spaces before, then print the body
            for (int j = 1; j <= TOTALHEIGHT + (i * (-5)); j++) {
                System.out.print(" ");
            }
            printMiddle();
            //Loop for spaces after, then print asterisk
            for (int j = 1; j <= (i - 1) * 5; j++) {
                System.out.print(" ");
            }
            //Loop for spaces before, then print the legs
            for (int j = 1; j <= TOTALHEIGHT + (i * (-5)); j++) {
                System.out.print(" ");
            }
            printBottom();
            //Loop for spaces after, then print asterisk
            for (int j = HEIGHT; j <= 0; --j) {
                System.out.print("---+");
            }
            System.out.println("|");
        }
        // for loop for printing the floor of asterisks
        for (int i = 1; i <= HEIGHT; i++) {
            System.out.print("+---+");
        }
    }
    public static void printTop() {
        System.out.print("+---+");
    }
    public static void printMiddle() {
        System.out.print("|   |");
    }
    public static void printBottom() {
        // System.out.print("+---+");
    }
}

这就是它的作用。

                    +---+ 
                    |   |                    |
               +---+---+ 
               |   |                    |
          +---+---+---+ 
          |   |                    |
     +---+---+---+---+ 
     |   |                    |
+---+---+---+---+---+ 
|   |                    |
+---++---++---++---++---+

谁能帮助我并指导我的代码?我希望有人能告诉我哪里出了问题以及应该改变什么。

【问题讨论】:

    标签: java for-loop ascii draw ascii-art


    【解决方案1】:

    这是我解决问题的方法。感谢您的拼图;)

    public class Staircase {
        public static final int SIZE = 5;
        public static final int STAIR_WIDTH = 5;
        public static final String TREAD = "-";
        public static final String RISER = "|";
        public static final String NOSING = "+";
        public static final String HOLLOW = " ";
    
        public static void main(String[] args)
        {
            StringBuilder step = new StringBuilder();
            for (int i = 0; i < (STAIR_WIDTH - 2); ++i) { step.append(TREAD); }
            StringBuilder hollow = new StringBuilder();
            for (int i = 0; i < (STAIR_WIDTH - 2); ++i) { hollow.append(HOLLOW); }
    
            StringBuilder tread = new StringBuilder();
            for (int i = 0; i < SIZE; ++i) { tread.append(NOSING + step); }
            tread.append(NOSING);
    
            StringBuilder riser = new StringBuilder();
            for (int i = 0; i < SIZE; ++i) { riser.append(RISER + hollow); }
            riser.append(RISER);
    
            for (int i = 0; i < SIZE; ++i) {
                int offset = tread.length() - (((STAIR_WIDTH - 1) * i) + STAIR_WIDTH);
                printSpaces(offset);
                System.out.println(tread.substring(offset));
                printSpaces(offset);
                System.out.println(riser.substring(offset));
            }
            System.out.println(tread);
        }
    
        public static void printSpaces(int count)
        {
            for (int i = 0; i < count; ++i)
                System.out.print(" ");
        }
    }
    

    【讨论】:

      【解决方案2】:
      public class Staircase {
          // You can change the height to any number and check
          public static final int HEIGHT = 5;
      
          public static void main(String[] args) {
              Staircase stairs = new Staircase();
              for (int j = 0; j < HEIGHT; j++) {
                  stairs.printSpace(j);
                  stairs.printTop(j);
                  stairs.printSpace(j);
                  stairs.printMiddle(j);
              }
             stairs.printTop(HEIGHT-1); // added for bottom line stairs 
          }
      
          public void printSpace(int j) {
              for (int i = j; i < HEIGHT - 1; i++) {
                  System.out.print("   ");
              }
          }
      
          public void printTop(int j) {
      
              for (int k = 0; k <= j; k++) {
                  System.out.print("+--");
              }
      
              System.out.print("+");
              System.out.println("");
          }
      
          public void printMiddle(int j) {
              for (int k = 0; k <= j; k++) {
                  System.out.print("|  ");
              }
              System.out.print("|");
              System.out.println("");
          }
      }
      

      【讨论】:

        【解决方案3】:

        我创建此代码是为了说明如何处理问题并逐步分解问题,直到您可以解决每个步骤。

        这是我众多测试结果之一的结果。

                        +---+
                        |   |
                    +---+---+
                    |   |   |
                +---+---+---+
                |   |   |   |
            +---+---+---+---+
            |   |   |   |   |
        +---+---+---+---+---+
        |   |   |   |   |   |
        +---+---+---+---+---+
        

        我做的第一件事是创建一个生成空白段的方法。我使用了StringBuilder 类来简化线段的构建和连接。

        一旦我开始工作,我就创建了创建台阶(平台)和托梁的方法。

        接下来,我创建了一个方法来创建一行输出。

        最后,我创建了一个创建整个楼梯的方法。

        这是完整的可运行代码。它可能不是最有效的代码,但我希望它是最易理解的代码之一。

        public class Staircase {
        
            public static void main(String[] args) {
                Staircase sc = new Staircase();
                System.out.println(sc.createStaircase(5));
            }
        
            public String createStaircase(int steps) {
                StringBuilder builder = new StringBuilder();
                int blankSteps = 0;
                String step = createStepSegment();
                String joist = createJoistSegment();
        
                for (int i = 1; i <= steps; i++) {
                    blankSteps = Math.max(0, steps - i);
                    builder.append(createLine(step, steps, blankSteps));
                    builder.append(createLine(joist, steps, blankSteps));
                }
                builder.append(createLine(step, steps, blankSteps));
        
                return builder.toString();
            }
        
            private StringBuilder createLine(String string, int steps, int blankSteps) {
                StringBuilder builder = new StringBuilder();
        
                int width = string.length() * blankSteps;
                builder.append(createBlankSegment(width));
        
                int boxSteps = steps - blankSteps;
                for (int i = 0; i < boxSteps; i++) {
                    builder.append(string);
                }
        
                builder.append(string.charAt(0));
                builder.append(System.lineSeparator());
        
                return builder;
            }
        
            private String createStepSegment() {
                return "+---";
            }
        
            private String createJoistSegment() {
                return "|   ";
            }
        
            private StringBuilder createBlankSegment(int length) {
                StringBuilder builder = new StringBuilder();
        
                for (int i = 0; i < length; i++) {
                    builder.append(" ");
                }
        
                return builder;
            }
        
        }
        

        【讨论】:

          【解决方案4】:

          又一个答案,所以你可以看到解决这个问题的很多很多方法。这一个使用单个绘制循环,并避免使用常量:

          public static void drawStaircase(int steps, 
                String stepTop, String stepLeft, String stepEmpty) {
              String endOfTopStep = stepTop.substring(0,1);  // "+---" => "+"
              String endOfMidStep = stepLeft.substring(0,1); // "|---" => "|"
              for (int row=0; row<steps;row++) {
                  // paint a top-of-step row
                  for (int col=0; col<steps; col++) {
                      boolean isEmpty = row+col+1 < steps;
                      System.out.print(isEmpty ? stepEmpty : stepTop);
                  }
                  System.out.println(endOfTopStep);
                  
                  // paint a middle-of-step row
                  for (int col=0; col<steps; col++) {
                      boolean isEmpty = row+col+1 < steps;
                      System.out.print(isEmpty ? stepEmpty : stepLeft);
                  }
                  System.out.println(endOfMidStep);
              }
              // paint bottom border
              for (int col=0; col<steps; col++) {
                  System.out.print(stepTop);
              }
              System.out.println(endOfTopStep);
          }
          
          public static void main(String ...args) {
              drawStaircase(4, "+---", "|   ", "    ");
          }
          

          【讨论】:

            【解决方案5】:

            你可以使用streams来搭建楼梯:

            int m = 5;
            String[] arr = IntStream.range(0, m).mapToObj(i -> {
                String[] arr1 = new String[m];
                String[] arr2 = new String[m];
                String[] arr3 = new String[m];
                IntStream.range(0, m).forEach(j -> {
                    if (i + j >= m - 1) {
                        if (j == m - 1) {
                            arr1[j] = "+---+";
                            arr2[j] = "|   |";
                            arr3[j] = "+---+";
                        } else {
                            arr1[j] = "+---";
                            arr2[j] = "|   ";
                            arr3[j] = "+---";
                        }
                    } else {
                        arr1[j] = "    ";
                        arr2[j] = "    ";
                    }
                });
                if (i == m - 1) {
                    return Stream.of(arr1, arr2, arr3);
                } else {
                    return Stream.of(arr1, arr2);
                }
            }).flatMap(Function.identity())
                    .map(row -> String.join("", row))
                    .toArray(String[]::new);
            
            // output
            Arrays.stream(arr).forEach(System.out::println);
            
                            +---+
                            |   |
                        +---+---+
                        |   |   |
                    +---+---+---+
                    |   |   |   |
                +---+---+---+---+
                |   |   |   |   |
            +---+---+---+---+---+
            |   |   |   |   |   |
            +---+---+---+---+---+
            

            【讨论】:

              【解决方案6】:

              您可以将楼梯表示为 zerosones 的二维数组,如下所示:

              [0, 0, 0, 0, 0, 1]
              [0, 0, 0, 0, 1, 1]
              [0, 0, 0, 1, 1, 1]
              [0, 0, 1, 1, 1, 1]
              [0, 1, 1, 1, 1, 1]
              [1, 1, 1, 1, 1, 1]
              

              然后你可以将这个数组的非空单元格表示为一个几乎是正方形,由两行组成:一行带有上边框和一行带有左边框。空单元格只是两行长度相同的空格。

              +---
              |   
              

              然后你可以将每一行的单元格连接成一行,并逐行输出。结果由两部分组成:带有右边框下边框行的二维数组行:

              n=6
                                  +---+
                                  |   |
                              +---+---+
                              |   |   |
                          +---+---+---+
                          |   |   |   |
                      +---+---+---+---+
                      |   |   |   |   |
                  +---+---+---+---+---+
                  |   |   |   |   |   |
              +---+---+---+---+---+---+
              |   |   |   |   |   |   |
              +---+---+---+---+---+---+
              

              Try it online!

              int n = 6;
              // 2d array of zeros and ones
              int[][] field = IntStream.range(0, n)
                      .mapToObj(i -> IntStream.range(0, n)
                              .map(j -> i + j < n - 1 ? 0 : 1)
                              .toArray())
                      .toArray(int[][]::new);
              
              String[] staircase = Stream.concat(
                      // rows of a 2d array with a right border
                      Arrays.stream(field)
                              .map(row -> IntStream.range(0, n)
                                      .mapToObj(i -> new String[]{
                                              // upper row of square with an upper border
                                              row[i] == 0 ? "    " : "+---"
                                                      // add a right border to the last element
                                                      + (i < n - 1 ? "" : "+"),
                                              // lower row of square with a left border
                                              row[i] == 0 ? "    " : "|   "
                                                      // add a right border to the last element
                                                      + (i < n - 1 ? "" : "|")})
                                      // reduce Stream<String[]> to a single array String[]
                                      .reduce((arr1, arr2) -> IntStream.range(0, 2)
                                              .mapToObj(j -> arr1[j] + arr2[j])
                                              .toArray(String[]::new))
                                      .orElse(new String[]{}))
                              .flatMap(Arrays::stream),
                      // lower border row
                      Stream.of(IntStream.range(0, n)
                              .mapToObj(i -> "+---" + (i < n - 1 ? "" : "+"))
                              .collect(Collectors.joining())))
                      .toArray(String[]::new);
              
              // output
              System.out.println("n=" + n);
              Arrays.stream(staircase).forEach(System.out::println);
              

              另见:Best way to make a border for a 2D array?

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2021-04-03
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-12-16
                • 2013-09-04
                • 1970-01-01
                • 2011-10-23
                相关资源
                最近更新 更多