java 金字塔 空心金字塔 空心菱形 详解(通俗易懂)
目录
一、前言
大家好,今天和大家分享以下用java如何打印出金字塔,空心金字塔以及空心菱形,我会一一进行代码演示,并尽量做一些注释,帮助大家理解。
二、金字塔:
1.思路分析:
首先我们希望代码的运行效果可以如下gif图所示:
分析I:仔细观察打印出的金字塔,我们发现从第一层开始,每一层的 * 的数量越来越多,而且呈现出1,3,5,7,9,11......2n-1 的规律,那么我们就权且以2n-1为每层 * 的数量。
分析II:除了最后一行外,每层的 * 前面都会有空格,所以我们要想打印出金字塔,就必须在每层先打印空格,再打印 * ,打印完一层的再打印下一层。那么,如何得知每层 * 前面需要打印空格的数量呢?下面我们以一个5层的金字塔为栗,一起找找规律。
如图:
假设我们就有这么一个5层的金字塔,从左边白线开始到中间的灰线,是1-5个位置 , 即金字塔中间灰线上的 * 是第五个位置,那么大家可以发现,在每层的前五个位置中,第五个的位置都是 * ,而每层前面的空格数则是4,3,2,1依次递减,到了第五层就没有空格了。即每层前五个位置状况如下:
第一层 ----- 4个空格+1个 *
第二层 ----- 3个空格+2个 *
第三层 ----- 2个空格+3个 *
第四层 ----- 1个空格+4个 *
第五层 ----- 0个空格+5个 *
结论:每层前面的空格数 = 总的楼层数 - 当前楼层编号。
2.代码演示:
👌,经过分析I和分析II,我们以及可以敲代码了,我们以Pyramid类作为演示类,
Pyramid类代码如下:
package csdn2022.pyramid;
import java.util.Scanner;
public class Pyramid {
public static void main(String[] args) {
//we try printing a solid pyramid.
Scanner sc = new Scanner(System.in);
System.out.println("------------------------------------------");
System.out.println("请输入你想得到的金字塔的层数:");
int floors = sc.nextInt();
for (int i = 1; i <= floors; ++i) {
/*
print " " before print "*"
The number of " " is (floors - i),
actually it's Total floor number minus current floor number.
打印出每层中 * 前面的空格,实际上空格的数量 = 总的楼层数 - 当前层编号。
*/
for (int k = 1; k <= (floors - i); ++k) {
System.out.print(" ");
} //第一个for打印出每层前面的空格
for (int j = 1; j <= (2*i-1); ++j) {
System.out.print("*");
} //第二个for打印出每层的 *
System.out.println();
//两个for完了,换行打印下一层
}
System.out.println("------------------------------------------");
sc.close();
}
}
运行效果:(如下gif图)
三、空心金字塔:
1.思路分析:
首先我们肯定希望代码的运行效果如下gif图所示:
分析I:金字塔每层 * 的数量,(此处为空心金字塔,可对应理解为金字塔每层需要输出的元素的多少), 以及每层第一个 * 之前需要打印出空格的数量,我们都在金字塔的思路分析中详细讲过,有同学如果是跳转过来看的,可以回去看看金字塔部分的思路分析。
分析II : 不难发现,空心金字塔和金字塔仅有一个区别,就是金字塔每层都是 * ,而空心金字塔每层除了首尾元素是 * 之外,其他都是空的,当然,除了最后一层。大家可以这么理解,将一个中间为空的大金字塔拆解为一层一层的,只要能够实现每层除了首尾为 * ,其他都是空的,那么把所有层叠加起来,也就实现了整体上为空的效果了。
Question:那么,如何用代码实现这个变动呢?
就像我们在金字塔中演示的代码一样,我们首先肯定需要两个变量 i 和 j 来分别保存 当前楼层编号 和 每层的元素,外层for循环为 i ,代表一层一层的打印,内层仍是两个for循环,第一个for循环打印出每层前面的空格,第二个for循环用于输出元素。但是第二个for循环要出现变化,我们需要在第二个for循环内增加一个if的条件语句进行判断,如果当前打印的是每层的首尾元素,或者正在打印最后一行的元素,那我们就输出 * ,反之,我们就输出空格,如此便可实现需求。
2.代码演示:
package csdn2022.pyramid;
import java.util.Scanner;
public class HollowPyramid {
public static void main(String[] args) {
//requirement : 打印出空心金字塔
int floors;
Scanner sc = new Scanner(System.in);
System.out.println("请输入空心金字塔总的楼层数");
floors = sc.nextInt(); //Enter the total number of floors
for (int i = 1; i <= floors; ++i) {
for1 :
for (int t = 1; t <= (floors - i); ++t) { //the number of " " boil down to (floors - i3)
System.out.print(" ");
}
/*
上面这个for1循环是为了打印出每层前面的空格数
而我们之前在讲金字塔的思路分析时,就已经说过每层前面的空格数是怎么来的。
*/
for (int j = 1; j <= (2*i - 1); ++j) { //remember here is "<="
if (j == 1 || j == (2*i - 1) || i == floors) { //Determine if it's the first position and the last position
System.out.print("*");
} else {
System.out.print(" "); //if it isn't, print the blank.
}
}
System.out.println();
}
System.out.println("------------------------------------------");
sc.close();
}
}
运行效果:(如下gif图)
四、空心菱形:
1.思路分析:
空心菱形,说白了就是给空心金字塔穿条裤子罢了,直接上运行效果GIF图看看:
Δ总思路:由于上半部分和下半部分是反的,所以我们先打印上半部分,再打印下半部分,而上半部分无非就是把空心金字塔的最后一层稍作变动,因此重点就是打印菱形的下半部分。
分析I :刚刚展示了空心金字塔的思路分析,想必你也有了一定自己的思路,起码有一点是肯定的,这里空心金字塔的“空心”的效果,其代码实现一定是与空心金字塔同理的。因此这里就不再赘述,跳转过来的小伙伴儿可以去看看空心金字塔的思路分析II。
分析II:需要注意的是,空心菱形中间最长的那一行不在和空心金字塔一样全是 * 了,而是也为空,这时我们只需要将if条件语句中的“是否为最后一行”这一判断给删去,只剩下“是否为首尾位置”的判断即可。
分析III(重要):由于我们打印是一层一层来打印的,而下半部分和上半部分截然相反,因此我们的代码实现也需要做出调整。下面我以一个5层的空心菱形为栗,给大家讲讲下半部分我们究竟该如何打印,如下图:
首先,由于下半部分与上半部分共用一行,因此,上半部分打印出中间行后,下半部分就会比上半部分少打印一层,体现在代码上就是外层for循环的条件语句从 i <= floors; 变成了 i < floors;,然后,就是下半部分打印的两个重点:①每层前的空格数,②每层对首尾元素的判断。
①先来说说每层前的空格数,注意看上图,下半部分,第一行前有1个空格,第二行前有两个空格,第三行前有三个空格.......,所以每层前面的空格数就等于当前楼层编号! ②再来说说每层对首尾元素的判断,注意看上图,每层除去前面的空格数,打印出的元素个数相当于把正的空心金字塔倒着打印了,此处为7,5,3,1。
大家想想在正的空心金字塔中是怎样的一个对应关系:1,2,3,4......i 层,分别对应了1,3,5,7......(2*i - 1)个元素,而再看现在倒着的空心金字塔,却是 1,2,3,4层对应了7,5,3,1个元素。
大家有没有想过,但凡将楼层编号或者每层元素个数中一个颠倒一下,那不就对上了!所以,大家这么来看:(注意,还是5层为栗,即floors = 5)
第1层 ---> 7个元素 ---> 2*(floors-1) - 1 个元素
第2层 ---> 5个元素 ---> 2*(floors-2) - 1 个元素
第3层 ---> 3个元素 ---> 2*(floors-3) - 1 个元素
第4层 ---> 1个元素 ---> 2*(floors-4) - 1 个元素
....................................................
第i层 ---> 2 * (5 - i) - 1个元素 ---> 2*(floors-i) - 1 个元素
👌,聪明的你一定已经发现了,将楼层编号与楼层数挂上钩之后,一切都回来了!没错,每层的元素个数就是 2*(floors - i) - 1。
对了,如果实在不理解的,强烈建议大家用试数法,自己带几个数进去,拿笔画画,多试几次自然明了。
2.代码演示:
package csdn2022.pyramid;
import java.util.Scanner;
public class HollowLozenge {
public static void main(String[] args) {
//requirement: print a hollow lozenge[ˈlɑːzɪndʒ] 打印一个空心菱形
Scanner sc = new Scanner(System.in);
System.out.println("请输入你想获得的菱形的规模:(以半个菱形的高度为基准)");
int floors;
floors = sc.nextInt();
//top half 上半部分代码原理与空心金字塔一致
for (int i = 1; i <= floors; ++i) {
for (int t = 1; t <= (floors - i); ++t) {
System.out.print(" ");
}
for (int j = 1; j <= (2*i - 1); ++j) { //remember here is "<="
if (j == 1 || j == (2*i - 1)) { //Determine if it's the first position and the last position
System.out.print("*"); //if it is, print the real element.
} else {
System.out.print(" "); //if it isn't, print the blank.
}
}
System.out.println();
}
//(The method of Try numbers is YYDS) 下半部分代码一时不易理解,但大家记住:试数法永远滴神
//bottom half 下半部分
for (int i = 1; i < floors; ++i) {//注意打印下半部分时,外层for循环这里变成 < 了,而不再是 <=
for (int t = 1; t <= i; ++t) {
System.out.print(" ");
}
/*
lozenge:top half and bottom half share the middle line,
so bottom half lacks one line.
in bottom half,the number of " " is just i(equals floors numerically)
*/
for (int j = 1; j <= 2*(floors - i) - 1; ++j) {
if (j == 1 || j == (2*(floors - i) - 1)) {
System.out.print("*");
} else {
System.out.print(" "); //if it isn't, print the blank.
}
}
System.out.println();
/*
How to understand the bottom half' code?
//(level - i) is truly likely the reverse arrangement: (下半部分像一个倒置排列的上半部分-1行)
like floors = 5,
floors - 1 = 4;
floors - 2 = 3;
floors - 3 = 2;
floors - 4 = 1;
so (floors - i)= like positive-going arrangement.
//remember it is "<=".
//Determine if it's the first position and the last position.
*/
}
sc.close();
}
}
运行效果:(如下GIF图)
五、完结撒❀:
其实,java打印空心XXX没有太大的难度,也没有考算法,无非是对自我编程思维的锻炼,恭喜你看到这里,感谢阅读!
System.out.println("------------------------------------------------------------------------------------------");
- 点赞
- 收藏
- 关注作者
评论(0)