如何使用Java绘制ASCII楼梯?

5

我一直在尝试用Java完成这个任务。对于我来说,这是一个复杂的绘图过程。

Q1 Write a simple Java program that prints a staircase or a figure as shown below:

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

我想出了一个解决方案,但还没有达到一半。这是我想出的代码:

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

这就是它的功能。

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

请问有人能帮助我并指导我的代码吗?如果有人能告诉我哪里出了问题,需要作出什么更改,我会很感激的。

6个回答

2
这是我对问题的解决方案。感谢谜题的提供;)
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(" ");
    }
}

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

1

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

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

1
我创建了这段代码来说明如何将一个问题分解成一步一步的小问题,直到你可以解决每个小问题。
以下是我的众多测试结果之一的结果。
                +---+
                |   |
            +---+---+
            |   |   |
        +---+---+---+
        |   |   |   |
    +---+---+---+---+
    |   |   |   |   |
+---+---+---+---+---+
|   |   |   |   |   |
+---+---+---+---+---+

我做的第一件事是创建一个生成空白线段的方法。我使用了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;
    }

}

1
您可以使用 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);

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

1
你可以将一个楼梯表示为一个由构成的二维数组,如下所示:
[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
                    +---+
                    |   |
                +---+---+
                |   |   |
            +---+---+---+
            |   |   |   |
        +---+---+---+---+
        |   |   |   |   |
    +---+---+---+---+---+
    |   |   |   |   |   |
+---+---+---+---+---+---+
|   |   |   |   |   |   |
+---+---+---+---+---+---+

在线尝试!

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

参见: 如何为二维数组制作边框的最佳方法?


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