今天面试时有道题没做出来,面试时大脑不够清醒,现在回过神来也并不算难。
题目:给定1、3、5三个数字,打印出对应的菱形形状,如下图
(我用X代表空格)
1:
+
3:
+
+++
+
5:
+
+++
+++++
+++
+
我是这样分析的:
来看这个结构,数字为1的时候可以先不考虑。
数字为3、5的时候有如下特点:
- 分别打印了3行和5行
- “+”最大数等于给定的值
所以我们已经确定了,最外圈要写个for循环,次数为给定的值;然后当循环到中间值时,打印的“+”数量等于给定的值。我想啊想,怎么想也解不出来这道题,然后就蒙了。不如换个思路?
把这个图形一分为三,中间是一部分,中间往上是上部分,中间往下是下部分。下部分为上部分的反转。然后把上部分和中间部分合为上部分,那么图形就是有上(上加中间)部分、下部分。
我们先来解决上部分:给定值为3时,上部分数量是2;给定值为5时上部分数量为3,获得上部分数量计算公式:x/2+1,那么外框已经有了
for(int i=1;i<=x/2+1;i++){
}
再看,图形由空格和“+”组成,空格数量从到大到小,分别为2、1、0,外框循环值为1、2、3,得出公式:循环总次数-1=x/2+1-i
for(int i=1;i<=x/2+1;i++){
for(int j=1;j<=x/2+1-i;j++){
System.out.print(" ");
}
}
“+”与空格正好相反,从小到大数量分别为1、3、5,都是奇数,得出公式:i*2-1
for(int i=1;i<=x/2+1;i++){
for(int j=1;j<=x/2+1-i;j++){
System.out.print(" ");
}
for(int k=1;k<=i*2-1;k++){
System.out.print("+");
}
//别忘了加换行
System.out.println();
}
上部分已经完成了,刚才说过,下部分就是上部分(没合并中间部分)的反转,我们上部分已经算出来空格和“+”的数量,把这个数量记录下来,然后做个反转就可以直接用了
int x = 3;
//虽然只用上部分的数据,避免数组越界,还是加上中间行的数量
int[] spaceSize = new int[x/2+1];
int[] addSize = new int[x/2+1];
for(int i=1;i<=x/2+1;i++){
for(int j=1;j<=x/2+1-i;j++){
System.out.print(" ");
}
//索引为总长度递减,等于是反转了数据
spaceSize[x/2+1 -i] = x/2+1-i;
for(int k=1;k<=i*2-1;k++){
System.out.print("+");
}
addSize[x/2+1 -i] = i*2-1;
//别忘了加换行
System.out.println();
}
最后,我们在用一个for循环外框,安装记录的数量来打印空格和“+”
int x = 3;
//虽然只用上部分的数据,避免数组越界,还是加上中间行的数量
int[] spaceSize = new int[x/2+1];
int[] addSize = new int[x/2+1];
for(int i=1;i<=x/2+1;i++){
for(int j=1;j<=x/2+1-i;j++){
System.out.print(" ");
}
//索引为总长度递减,等于是反转了数据
spaceSize[x/2+1 -i] = x/2+1-i;
for(int k=1;k<=i*2-1;k++){
System.out.print("+");
}
addSize[x/2+1 -i] = i*2-1;
//别忘了加换行
System.out.println();
}
//i=1,直接去掉中间部分
for(int i=1;i<=x/2+1;i++){
for(int j=0;j<spaceSize[i];j++){
//这里可能不好理解,空格的数量已经记录在数组spaceSize中
//spaceSize的值就是要打印的个数
System.out.print(" ");
}
for(int k=0;k<addSize[i];k++){
System.out.print("+");
}
System.out.println();
}
结果:
x=3:
+
+++
+
x=5:
+
+++
+++++
+++
+
总结:不要晚上面试,哭~~~