导语:今天和同事聊天,他提到一道面试题,题目大体是,使用控制台输出一个菱形(边长相等),并且每行都是奇数个,怎么写?
首先要审题,1、控制台输出菱形 2、每行是奇数个。
*
***
*****
*******
*********
***********
*********
*******
*****
***
*
上图是需要输出的结果。
分析:如何构建一个菱形?
大体上分3步:
第一步:画出一个直角的梯形:
******
*******
********
*********
**********
***********
************
*************
**************
***************
****************
第二步:把该梯形的右下“脚”去掉!
******
*******
********
*********
**********
***********
**********
*********
********
*******
******
第三步:将左边的部分*替换成空格:
*
***
*****
*******
*********
***********
*********
*******
*****
***
*
通过以上三步即可构造成一个菱形,问题解决。
下面说一下具体的思路。
第一步的实现:
这一步其实很简单,首先根据传入的奇数(number=11)来确定第一行要输入的[星号]的个数(columnFirst),为columnFirst = (number/2) + 1;以下每一行加一个[星号]即可,详细代码如下:
public void printDiamond(int number) {
final int total = number / 2 + 1;// 首行的列数
for (int row = 1; row <= number; row++) {
int count = total + (row - 1);// 每行需要的列数
for (int column = 0; column < count; column++) {
System.out.print("*");
}
System.out.println();// 换行
}
}
以上代码即可实现输出步骤一中的直角梯形。
第二步的实现:
从第一步到这一步需要发现一条规律,即:
****** 1
******* 2
******** 3
********* 4
********** 5
*********** 6
************(2*1)=2 7
*************2*2=4 8
**************2*3=6 9
***************2*4=8 10
****************2*5=10 11
上图中,第6行是整个菱形的中间,星号数量为11个,本来从第6行起,应该逐个递减,每行递减1个星号,可第7行(和第6行相比)却多了一个星号,这一多一少就是多了1x2=2个星号;第8行(和第6行相比)应该去掉2个星号,可现实是多了2个星号,这一多一少就是多了2x2=4个星号;第9行(和第6行相比)应该去掉3个星号,可现实却是多了3个星号,这一多一少就是多了3x2=6个星号;以此类推。可以发现:从第7行开始,7减去中间值6等于1,8减去中间值6等于2,9减去中间值6等于3,以此类推,可以发现:(行数-中间值(6))乘以2即为需要去掉的右下“脚”。具体代码如下:
public void printDiamond(int number) {
final int total = number / 2 + 1;// 首行的列数
for (int row = 1; row <= number; row++) {
int count = total + (row - 1);// 每行需要的列数
if (row > total) {
count = count - (2 * (row - total));
}
for (int column = 0; column < count; column++) {
System.out.print("*");
}
System.out.println();// 换行
}
}
以上代码即可实现输出步骤二中的去掉直角梯形的右下“脚”。
第三步的实现:
从第二步到第三步还需要发现一个规律,即:
******5 1
*******4 2
********3 3
*********2 4
**********1 5
***********0 6
**********1 7
*********2 8
********3 9
*******4 10
******5 11
上图中,需要把左边多余的星号替换成空格,第一行需要替换钱5个空格,第二行需要替换前4个空格,第三行需要替换钱三个空格,以此类推,结合右边的行数会发现:将第一行的行数1减去中间数6等于-5,取绝对值之后为5;第二行的行数2减去中间数6等于-4,取绝对值之后为4;…第七行的行数7减去中间数6等于1,取绝对值之后为1;第八行的行数8减去中间数6等于2,取绝对值之后为2;…第十一行的行数11减去中间数6等于5,取绝对值之后为5;以上规律可以发现:行数减去中间数然后取绝对值正好是当前行应该替换成空格的数量。,具体代码如下:
public void printDiamond(int number) {
final int total = number / 2 + 1;// 首行的列数
for (int row = 1; row <= number; row++) {
int count = total + (row - 1);// 每行需要的列数
if (row > total) {
count = count - (2 * (row - total));
}
int columnSpace = Math.abs(row - total);// 每行需要的空格数
for (int column = 0; column < count; column++) {
if (column < columnSpace) {
System.out.print(" ");
} else {
System.out.print("*");
}
}
System.out.println();// 换行
}
}
最终控制台输出结果为:
*
***
*****
*******
*********
***********
*********
*******
*****
***
*
问题解决。
END