【问题标题】:Drawing numeric diamond绘制数字菱形
【发布时间】:2015-11-06 14:29:11
【问题描述】:
我需要绘制一个数字菱形,例如高度为9:
1
222
33333
4444444
555555555
4444444
33333
222
1
我编写了代码,并设法获得了相同的钻石,但带有星星。我想要这些数字。我怎样才能做到这一点?这是我到目前为止所做的:
for (int i = 1; i < 10; i += 2) {
for (int j = 0; j < 9 - i / 2; j++)
System.out.print(" ");
for (int j = 0; j < i; j++)
System.out.print("a");
System.out.print("\n");
}
for (int i = 7; i > 0; i -= 2) {
for (int j = 0; j < 9 - i / 2; j++)
System.out.print(" ");
for (int j = 0; j < i; j++)
System.out.print("b");
System.out.print("\n");
}
【问题讨论】:
标签:
java
methods
numeric
ascii-art
【解决方案1】:
关于您的代码:
-
System.out.print("\n"); 应替换为 System.out.println()。
- 您应该使用动态高度而不是硬编码 9。
- 它打印出正确的图案,只有打印出的图案是错误的:而不是打印
"a" 和"b",你应该打印循环的索引,看看你能从那里得到什么。这是@Tsung-Ting Kuo 解决方案。
在我看来,你可以用更少的循环和更容易理解的方式来做到这一点。考虑以下算法:
- 对于模式的每一行(因此该行从 0 到
height 不包括在内)
- 对于模式的每一列(因此列从 0 到
height 除外)
- 当我们在图表的右上角、左上角、右下角或左下角时,我们需要打印一个空格。
- 左上角:这是当列小于
height/2-row-1时
- 左下角:这是当列小于
row-height/2时
- 将这两个表达式合并为一个,这是当列小于
height/2 - min 时,min = Math.min(row+1, height-row)。
- 右上角:这是当列大于
height/2+row+1时
- 右下:这是当列大于
height/2+height-row时
- 将这两个表达式合并为一个,这是当列大于
height/2 + min 时,min = Math.min(row+1, height-row)。
- 否则,我们需要打印
Math.min(row+1, height-row)。
转成代码:
public static void main(String[] args) {
int height = 9;
for (int row = 0; row < height; row++) {
for (int column = 0; column < height; column++) {
int min = Math.min(row+1, height-row);
if (column <= height / 2 - min || column >= height / 2 + min) {
System.out.print(" ");
} else {
System.out.print(min);
}
}
System.out.println();
}
}
示例输出:
1
222
33333
4444444
555555555
4444444
33333
222
1
【解决方案2】:
java-11
使用作为 Java-11 的一部分引入的String#repeat,您可以使用单循环来完成。
public class Main {
public static void main(String[] args) {
final int MID_ROW_NUM = 5;
for (int i = 1 - MID_ROW_NUM; i < MID_ROW_NUM; i++) {
int x = Math.abs(i);
System.out.println(" ".repeat(x) + String.valueOf(MID_ROW_NUM - x).repeat((MID_ROW_NUM - x) * 2 - 1));
}
}
}
输出:
1
222
33333
4444444
555555555
4444444
33333
222
1
您只需将空格量增加一个字符即可打印菱形的变体:
public class Main {
public static void main(String[] args) {
final int MID_ROW_NUM = 5;
for (int i = 1 - MID_ROW_NUM; i < MID_ROW_NUM; i++) {
int x = Math.abs(i);
System.out.println(" ".repeat(x) + ((MID_ROW_NUM - x) + " ").repeat((MID_ROW_NUM - x) * 2 - 1));
}
}
}
输出:
1
2 2 2
3 3 3 3 3
4 4 4 4 4 4 4
5 5 5 5 5 5 5 5 5
4 4 4 4 4 4 4
3 3 3 3 3
2 2 2
1
【解决方案3】:
请试试下面的代码(我已经测试过了),只改两个print:
public static void main(String[] args) throws Exception {
for (int i = 1; i < 10; i += 2) {
for (int j = 0; j < 9 - i / 2; j++)
System.out.print(" ");
for (int j = 0; j < i; j++)
System.out.print(i/2+1); // Change here
System.out.print("\n");
}
for (int i = 7; i > 0; i -= 2) {
for (int j = 0; j < 9 - i / 2; j++)
System.out.print(" ");
for (int j = 0; j < i; j++)
System.out.print(i/2+1); // Change here
System.out.print("\n");
}
}
输出:
1
222
33333
4444444
555555555
4444444
33333
222
1
【解决方案4】:
您可以使用IntStream 绘制一个数字菱形,如下所示:
int m = 5;
int n = 5;
String[][] arr = IntStream
.rangeClosed(-m, m)
.map(Math::abs)
.mapToObj(i -> IntStream
.rangeClosed(-n, n)
.map(Math::abs)
.mapToObj(j -> i + j > Math.max(m, n) ? " " : "" + (m - i))
.toArray(String[]::new))
.toArray(String[][]::new);
// formatted output
Arrays.stream(arr).map(row -> String.join(" ", row)).forEach(System.out::println);
0
1 1 1
2 2 2 2 2
3 3 3 3 3 3 3
4 4 4 4 4 4 4 4 4
5 5 5 5 5 5 5 5 5 5 5
4 4 4 4 4 4 4 4 4
3 3 3 3 3 3 3
2 2 2 2 2
1 1 1
0
另见:Filling a 2d array with numbers in a rhombus form • Print this diamond