如何用Java画一个ASCII楼梯?
How to draw an ASCII staircase with Java?
我一直在努力在 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("+---+");
}
}
这就是它的作用。
+---+
| | |
+---+---+
| | |
+---+---+---+
| | |
+---+---+---+---+
| | |
+---+---+---+---+---+
| | |
+---++---++---++---++---+
任何人都可以帮助我并指导我编写代码吗?我希望有人能告诉我哪里出了问题以及应该更改什么。
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("");
}
}
这是我解决问题的方法。感谢您的拼图 ;)
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(" ");
}
}
另一个答案,所以你可以看到很多很多解决这个问题的方法。这个使用单个绘制循环,并避免使用常量:
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, "+---", "| ", " ");
}
我创建这段代码是为了说明如何解决问题并逐步分解它,直到您可以解决每个步骤。
这是我众多测试结果之一的结果。
+---+
| |
+---+---+
| | |
+---+---+---+
| | | |
+---+---+---+---+
| | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
我做的第一件事是创建一个方法来生成空白段。我使用 StringBuilder class 来更轻松地构建线段并连接它们。
完成该工作后,我创建了创建台阶(平台)和托梁的方法。
接下来,我创建了一个方法来创建一行输出。
最后,我创建了一个创建整个楼梯的方法。
这是完整的可运行代码。它可能不是最高效的代码,但我希望它是最易于理解的代码之一。
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;
}
}
您可以使用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);
+---+
| |
+---+---+
| | |
+---+---+---+
| | | |
+---+---+---+---+
| | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
您可以将楼梯表示为 zeros 和 ones 的二维数组,如下所示:
[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);
另请参阅:Best way to make a border for a 2D array?
我一直在努力在 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("+---+");
}
}
这就是它的作用。
+---+
| | |
+---+---+
| | |
+---+---+---+
| | |
+---+---+---+---+
| | |
+---+---+---+---+---+
| | |
+---++---++---++---++---+
任何人都可以帮助我并指导我编写代码吗?我希望有人能告诉我哪里出了问题以及应该更改什么。
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("");
}
}
这是我解决问题的方法。感谢您的拼图 ;)
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(" ");
}
}
另一个答案,所以你可以看到很多很多解决这个问题的方法。这个使用单个绘制循环,并避免使用常量:
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, "+---", "| ", " ");
}
我创建这段代码是为了说明如何解决问题并逐步分解它,直到您可以解决每个步骤。
这是我众多测试结果之一的结果。
+---+
| |
+---+---+
| | |
+---+---+---+
| | | |
+---+---+---+---+
| | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
我做的第一件事是创建一个方法来生成空白段。我使用 StringBuilder class 来更轻松地构建线段并连接它们。
完成该工作后,我创建了创建台阶(平台)和托梁的方法。
接下来,我创建了一个方法来创建一行输出。
最后,我创建了一个创建整个楼梯的方法。
这是完整的可运行代码。它可能不是最高效的代码,但我希望它是最易于理解的代码之一。
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;
}
}
您可以使用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);
+---+
| |
+---+---+
| | |
+---+---+---+
| | | |
+---+---+---+---+
| | | | |
+---+---+---+---+---+
| | | | | |
+---+---+---+---+---+
您可以将楼梯表示为 zeros 和 ones 的二维数组,如下所示:
[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);
另请参阅:Best way to make a border for a 2D array?