问题描述
我正在学习 Java,目前正在尝试使用该程序制作一些 ASCII 艺术。我能够制作空心钻石,但我正在努力制作“棋盘格”或方形图案。我正在尝试创建如下所示的内容:
*** *** ***
*** *** ***
出于某种原因,它一直这样出现:
***
***
***
***
我知道问题出在我的 for 循环上。由于我刚刚了解了嵌套循环,我仍在尝试理解其中的逻辑。我的中间循环控制空格,无论我为 s
(我的递增变量)设置什么值,它仍然会使模式变得奇怪。
这是我的代码:
public class ASCII_Art {
public static void squares() {
System.out.println("***\n*** ");
}
public static void main(String[] args) {
for (int i = 0; i <= 5; i++) {
for (int y = 0; y < i - 4; y++) {
squares();
System.out.print(" ");
squares();
}
}
}
}
我做了一个 square 方法,因为我读到这些方法让一切变得更清晰、更容易,因为你不必多次重写相同的代码。
解决方法
这里有几个问题。
-
正如其他人所指出的,
\n
创建了一个新行,
像这样。\t
另一方面,创建一个缩进,\t
就是您想要的。 -
在您的
squares
函数中,您只打印两个***
。相反,打印 3。 -
由于
squares
已经打印了一行,因此您只需要一个最多为 2 的 for 循环。执行此操作的传统方法是int i = 0; i < 2
。
以下是完整更正的代码(我修复了缩进、重新加括号并添加了 main
方法):
public class ASCII_Art
{
public static void squares(){
System.out.println("***\t***\t***");
}
public static void main(String[] args) {
for (int i = 0; i < 2; i++) {
squares();
}
}
}
或者,由于您的 squares
方法实际上没有提供太多价值,您可以改为这样做:
public class ASCII_Art
{
public static void main(String[] args) {
for (int i = 0; i < 2; i++) {
System.out.println("***\t***\t***");
}
}
}
如果您想进一步自定义您的 ASCII 艺术,您可以创建一个带有 3 个参数的函数:一个用于 *
的数量,一个用于一行中的星号块数,一个用于行数。我会让你自己弄清楚...
所以基本上这里的问题是你的 square 方法打印出三个星号,然后换行。然后你不能回到上一行,这就是为什么第一个方块看起来不错,但其他方块看起来不合适。如果您查看输出,则会打印第一个方块。然后打印空格,然后打印另一个正方形。但是第二个方格不是从第一行开始的。它从第二个开始,所以最终发生的是打印前三个星号,然后 \n 告诉它换行,然后打印其他三个星号,这就是它们看起来分开的原因。就像其他人建议的那样,使用 \t,而不是 \n。
,您可以将棋盘可视化为Boolean[][]
矩阵8x8
,其中每个元素是:
m[i][j] = (i - j) % 2 != 0;
然后您可以将每个 Boolean
表示为一个实心或空心的正方形,然后将这些正方形并排连接成一个线,然后逐行输出。
**** **** **** ****
**** **** **** ****
**** **** **** ****
**** **** **** ****
**** **** **** ****
**** **** **** ****
**** **** **** ****
**** **** **** ****
**** **** **** ****
**** **** **** ****
**** **** **** ****
**** **** **** ****
**** **** **** ****
**** **** **** ****
**** **** **** ****
**** **** **** ****
三种方法:创建空格和星号的正方形,创建行的正方形,以及输出字段的行。
public static void main(String[] args) {
// field size
int n = 8;
// square size
int s = 2;
// output a checkerboard
IntStream.range(0,n)
// i - height,j - width
// prepare a row of booleans
// Stream<Boolean[]>
.mapToObj(i -> IntStream.range(0,n)
// filled or hollow - true or false
.mapToObj(j -> (i - j) % 2 != 0)
.toArray(Boolean[]::new))
// prepare a line of squares for each row
// Stream<String[]>
.map(row -> line(row,s))
// Stream<String>
.flatMap(Arrays::stream)
// output line by line
.forEach(System.out::println);
}
public static String[] line(Boolean[] arr,int size) {
return Arrays.stream(arr)
// prepare a square for each element
// Stream<String[]>
.map(bool -> square(size,bool))
// sequentially join squares side-by-side
.reduce((arr1,arr2) -> IntStream.range(0,size)
.mapToObj(i -> arr1[i] + arr2[i])
.toArray(String[]::new))
.orElse(null);
}
public static String[] square(int size,boolean filled) {
return IntStream.range(0,size)
// i - height,j - width
.mapToObj(i -> IntStream.range(0,size * 2)
.mapToObj(j -> filled ? "*" : " ")
.collect(Collectors.joining()))
.toArray(String[]::new);
}