很多人,打印菱形在控制台的思路是,把菱形上下拆分,分两段很接近的代码来打印,其实这样代码很不好看,并且不好阅读。我们知道,要打印的图案是这种:
*
***
*****
***
*
满足上下对称,左右对称,那么,你能不能也弄一个二重循环,同样是对称的?很简单,首先我们要抛开习惯性思维,for循环不一定要在0开始或者0结束。我们可以让循环从-c到c,这样就轻松产生一个对称的(只要取个绝对值)。我们把菱形的中心看成是坐标(0,0),那么,会输出星号的坐标,是( |x| + |y| <= c )的点。由此可得:
public static void print(int size) {
// size是这个菱形的半径,直径会是size * 2 + 1
int x, y;
for (y = -size; y <= size; y++) {
StringBuffer temp = new StringBuffer("");
for (x = -size; x <= size; x++) {
// x和y各自的绝对值的和,即 |x| + |y| <= size
if ((x >= 0 ? x : -x) + (y >= 0 ? y : -y) <= size)
temp.append('*');
else
temp.append(' ');
}
System.out.println(temp.toString());
}
}
如果我需要得到空心菱形呢?非常简单,因为菱形边界上的点,满足的是|x| + |y| == c。所以,我们只要把那个if里的小于等于号,改成双等于号== 就可以了。如果我不要*号,我要最外层是字母A,然后里一层是B这样呢?即:
A
ABA
ABCBA
ABA
A
那么,我们只要在putchar那里做一个字符计算:
public static void print(int size) {
// size是这个菱形的半径,直径会是size * 2 + 1
int x, y;
for (y = -size; y <= size; y++) {
StringBuffer temp = new StringBuffer("");
for (x = -size; x <= size; x++) {
// x和y各自的绝对值的和,即 |x| + |y| <= size
if ((x >= 0 ? x : -x) + (y >= 0 ? y : -y) <= size) {
int gap = size - (x >= 0 ? x : -x) - (y >= 0 ? y : -y);
// 留意这里的计算方法
temp.append((char) ('A' + gap));
} else
temp.append(' ');
}
System.out.println(temp.toString());
}
}
类似地,如果我们要打印的是X形:
* *
* *
*
* *
* *
同样可以利用这个思路完成,x与y满足|x| = |y|等式,我们只要把那个if里的条件改成|x| == |y|就可以了。
public static void print(int size) {
// size是这个菱形的半径,直径会是size * 2 + 1
int x, y;
for (y = -size; y <= size; y++) {
StringBuffer temp = new StringBuffer("");
for (x = -size; x <= size; x++) {
// x和y各自的绝对值的和,即 |x| + |y| <= size
if ((x >= 0 ? x : -x) == (y >= 0 ? y : -y)) {
temp.append("*");
} else
temp.append(' ');
}
System.out.println(temp.toString());
}
}