700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > java的嵌套for循环例子:打印直角三角形 等腰三角形 菱形(超详细思路)

java的嵌套for循环例子:打印直角三角形 等腰三角形 菱形(超详细思路)

时间:2024-02-16 16:44:06

相关推荐

java的嵌套for循环例子:打印直角三角形 等腰三角形 菱形(超详细思路)

打印直角三角形、等腰三角形、菱形

(1) 西南方向的直角三角形(2) 西北方向的直角三角形(3) 东南方向的直角三角形(4) 东北方向的直角三角形(5) 内部没有空格的等腰三角形(6) 内部没有空格的倒立的等腰三角形(7) 内部有空格的等腰三角形(8) 内部有空格的倒立的等腰三角形(9) 菱形总结

(1) 西南方向的直角三角形

我们肯定知道打印3行3列的矩形怎么做,就是外循环 i 从1到3,内循环 j 从1到3。

但是很明显,如果我们想要打印西南方向的直角三角形,每次内循环 j 的范围是不一样的。问题来了:

我们如何控制它在第一行的时候,在 j = 1打印完星星后停止;

在第一行的时候,在 j = 2打印完星星后停止;在 j = 3打印完星星后停止?

如果有一个停止指针能在执行第一次外循环的时候指向 1,在执行第二次外循环的时候指向 2, 在执行第三次外循环的时候指向 3就好了!

为了便于观察 i 和 j 的关系,将 i 和 j 放到同一水平去画,如下图:

看上图,我们会发现,i 所在的位置,正好是我们需要的《停止指针》的位置。于是就能写出代码,注意一下,每一行结束的时候需要回车,也就是说内循环结束之后循环打印回车。

for(int i=1; i<=3; i++){for(int j=1; j<=i; j++){System.out.print("*");}System.out.println();}

//运行结果******

(2) 西北方向的直角三角形

对于西北方向的直角三角形,看上图,我们发现 i 的位置并不是我们想要的《停止打印星星的位置》

那么问题来了,《停止打印星星的位置》(我们称为停止指针指向的位置)是在哪呢?

虽然此时我们不能将 i 作为《停止指针》,但是我们可以找找我们需要的《停止指针》跟 i 的关系。我们知道 i 分别是 1、2、3,而我们需要的《停止指针》的位置分别是 3、2、1,所以我们可以把 4 - i 作为《停止指针》。

(实际上没有停止指针这种说法,我只是为了便于理解打得一个比喻)

for(int i=1; i<=3; i++){for(int j=1; j<=4-i; j++){System.out.print("*");}System.out.println();}

//运行结果******

那么其他人也是这样想的吗?那倒未必!因为我们发现,上面我们的分析中一直都有一个前提假设,我们假设了 j 表示列标,什么意思呢?意思是:我们在打印第1行第1个星星的时候,是不是满足了 i = 1,j = 1?

但实际上呢,我们打印这个直角三角形并没有说 i 必须表示行号,j 必须表示列号,难道说 j = 2的时候我就必须得打印第2列的东西吗?事实上!无论i 或者 j 等于多少,他打印的顺序都是从左到右一个个来。

所以!实际上我们只需要控制第一次外循环打印3次星星,第二次外循环打印2次星星,第三次外循环打印1次星星。此时,问题就变成了:如何控制在 i = 1的时候内循环执行三次打印星星,在 i = 2的时候内循环执行两次打印星星,在 i = 3 的时候内循环执行1次打印星星?

我们知道,控制内循环执行次数是取决于 j 的范围,那么我们如何让 j 的范围 在 每次外循环不同的时候不同呢? 其实就是像上面那样,借助 i 。我们知道 i 分别是 1、2、3,那我们的 j 一开始应该在 i 的右边还是左边呢,明显我们最终的目标是 分别循环 3、2、1,所以 j 应该是在 i 的右边,这样的话 i 在增加的时候,i 和 j的距离就会慢慢减少。那么 j 应该 定为多少呢?

看下图就明白, j 应该定为 3。

可能你觉得废话很多,但是其实关键就一句话,《关注 i 和 j 的距离,它们的距离决定了此次外循环的内循环执行次数》

for(int i=1; i<=3; i++){for(int j=i; j<=3; j++){//或者 for(int j=3; j>=i; j--)System.out.print("*");}System.out.println();}

//运行结果******

(3) 东南方向的直角三角形

方法1:

我们知道,打印是从左到右的。很显然,前面两种情况星星在空格前面,我们是不用去管空格的。但是现在,空格在星星前面,我们必须得打印空格,然后再打印星星。

根据前面的经验,我们发现这些问题的关键点无非就是《找空格和星星的分界点》。

从上图可以看出,分界点就是在 4 - i 的位置。那我们只需要让 j 从1到3扫描,在扫描到 i 的位置之前打印空格,扫描到 i 的位置之后打印星星。

for(int i=1; i<=3; i++){for(int j=1; j<=3; j++){if(j < 4 - i){System.out.print(" ");}else{System.out.print("*");}}System.out.println();}

******

方法2:

我们是让j从1到3扫描,也就是说整行都扫描了,然后每一列需要打印什么,再分情况讨论,分情况的方法是设置《停止指针》。

那么我们可不可以先每一行前面的空格都打印好,再去打印每一行的星星呢?

那么如何把每一行前面的空格都打印好呢?前面我们说那个《关注 i 和 j 的距离》就发挥了作用,其实我们想第一行打印2个空格,第二行打印1个空格,第三行打印0个空格,无非不就是《控制 j 的范围》,控制 j 的范围无非就是要《关注 i 和 j 的距离》。

看下图。明显这次要设置 j 从i到2。

打印完每一行的空格之后,就要打印每一行的星星。

第一行打印1个星星,第二行打印2个星星,第三行3个星星。

所以控制 i 和 j 的距离分别是 1,2,3就行啦。那 j 的范围就是 1到 i 。

for(int i=1; i<=3; i++){for(int j=i; j<=2; j++){System.out.print(" ");}for(int j=1; j<=i; j++){System.out.print("*");}System.out.println();}

******

方法3:

前面的思路都是 j 从左到右扫描,如果j 从右到左扫描呢?

然后你就发现,在方法1中 j 从左到右扫描,分界点是在 4-i 的位置(1到 3-i 要打印空格,之后要打印星星)。

如果 j 从右到左扫描,分界点是在 i 的位置(在 3 到 i+1 要打印空格,然后就是打印星星),看下图就明白,红色表示打印每一行的空格数分别是2, 1,0,黑色表示打印每一行的星星数分别是1, 2, 3, j是从3到1扫描。

显然方法3跟方法1的核心思想都是《找到一个分界点》,以及《关注 i 和 j 的距离》,两种方法互为相反的思路,但是最终的目的都是跟《i 和 j 的距离》有关。

事实上!我认为方法1才是最简单的思路,因为方法1中的 j 是表示列号的,而方法2和方法3的 j 都不是表示 列号!但是我为什么要把各种思路想一想,因为各种思路都想过以后,发现他们都是如出一辙!不管他们怎么弄,他们都是要控制第一行打印2个空格,然后打印1个星星;第二行打印1个空格,然后打印两个星星.;第三行打印0个空格,然后打印3个星星。

for(int i=1; i<=3; i++){for(int j=3; j>=1; j--){if(j > i){System.out.print(" ");}else{System.out.print("*");}}System.out.println();}

******

(4) 东北方向的直角三角形

有了前三个的经验,我们来整理一下思路。

首先,一看他前面是空格后面是星星,说明空格和星星是要分别处理的。

方法一是 j 从1到3扫描,然后分界点之前打印空格,分界点之后打印星星,分界点明显是 i 的位置。

for(int i=1; i<=3; i++){for(int j=1; j<=3; j++){if(j < i){System.out.print(" ");}else{System.out.print("*");}}System.out.println();

******

方法二是先把每一行的空格打印出来,把每一行的空格数都看一下,分别是 0,1, 2,这个距离明显是在增加。

我们知道 i 分别是 1,2, 3,要让 i 和 j 的距离增加,明显是要把 j 放在左边,然后想想,

当 i = 1的时候,j 在什么位置,i 和 j 的距离为0?肯定是越过 i 的位置,j 要放在左边,j 又要越过 i,推理出 j = 2

当 i = 2的时候,j 在什么位置,i 和 j 的距离为1?肯定是跟 i 重合的位置,推理出 j = 2

当 i = 3的时候,j 在什么位置,i 和 j 的距离为2?推理出 j = 2。

上面三种推理方式,无论选哪种都能推理出 j = 2,建议选第二种推理方式。

所以 j 的范围是 2 到 i。

(东南方向的直角三角形我们分析出是 i 到 2,如果你看不懂为什么这是 2到 i,可见只是反了过来,可以去看看东南方向的直角三角形那张 x 轴的图)

再看看每一行的星星数,分别是 3,2, 1。 距离在减少,i 分别是 1, 2,3,既然 i 在向x轴的正方向增加,想让 i 和 j 的距离减少,那 j 必然是站在 i 的右边。

当 i = 3的是,j 在什么位置, i 和 j 的距离为1?明显是 j = 3的时候。

所以 j 的范围是 i 到 3

最后,别忘了每一行结束要打印回车。

for(int i=1; i<=3; i++){for(int j=i; j<=1; j++){System.out.print(" ");}for(int j=3; j>=i; j--){System.out.print("*");}System.out.println();}

******

(5) 内部没有空格的等腰三角形

经过前面一波猛如虎的分析,突然就发现管它是什么形状,都是一样的分析方法。

第一,空格前面有星星,那肯定要先打印空格,再打印星星。

第二,观察星星前面的每一行空格是多少,分别是2,1,0,

距离在减少,由于i分别是1, 2,3在增加,所以 j 必定在 i 的右边。再看距离为1的时候 i =2,所以 j的范围肯定是 i 到 2。

(看下图就明白我在说啥,注意,我所说的距离是包括首尾的哈,比如我说 i = 1和 j =2的距离是2,意思是包括1和2。比如 i 和 j都是2的时候,距离是1,因为要包括2本身。其实严格来说不能称为《距离》,不过反正你懂什么我说的这个距离什么意思就行)

第三,观察每一行几个星星,分别是1, 3, 5,明显都是奇数,所以 j 的范围是 1到2*i - 1。

我们为什么不去分析 i 和 j 的距离? 因为此次的距离不是逐渐加1或者减1变化的,跟 i 的步长不一致,如果要分析的话,如下图所示,j 应该分别是1,4,7,等差数列公式 1+(i-1)3 = 3i - 2。分析出 j 的范围是 i 到 3*i-2。你还真别说,也可以这样分析。

这启示我们,控制这个距离为1, 3,5这种步长跟 i 的步长不一致的情况,应该直接去看 1,3,5本身跟 i 有什么联系,能否将他们表达成跟 i 有关的表达式,然后从1开始,就能产生1,3,5这样不同的距离。

for(int i=1; i<=3; i++){for(int j=i; j<=2; j++){System.out.print(" ");}for(int j=1; j<=2*i-1; j++){System.out.print("*");}System.out.println();}

for(int i=1; i<=3; i++){for(int j=i; j<=2; j++){System.out.print(" ");}for(int j=i; j<=3*i-2; j++){System.out.print("*");}System.out.println();}

*********

(6) 内部没有空格的倒立的等腰三角形

先打前面的空格再星星。

前面的空格数分别是0, 1,2,所以 j 的范围是 2 到 i

星星数分别是 5, 3,1,所以 j 的范围是 1 到 5+(i-1)*(-2)(等差数列公式)即 1 到 -2i+7

for(int i=1; i<=3; i++){for(int j=2; j<=i; j++){System.out.print(" ");}for(int j=1; j<=-2*i+7; j++){System.out.print("*");}System.out.println();}

*********

(7) 内部有空格的等腰三角形

可以把星星和后面的一个空格看做整体,然后就直接转换成了东南方向的直角三角形的问题。

for(int i=1; i<=3; i++){for(int j=1; j<=3; j++){if(j < 4 - i){System.out.print(" ");}else{System.out.print("* ");}}System.out.println();}

** ** * *

(8) 内部有空格的倒立的等腰三角形

其实就是东北方向直角三角形的问题

一看前面的空格数,0,1,2 所以 j 的范围 2 到 i

星星数 3, 2,1 所以 j 的范围是 i 到 3 或者说 3 到 i

for(int i=1; i<=3; i++){for(int j=2; j<=i; j++){System.out.print(" ");}for(int j=i; j<=3; j++){//for(int j=3; j>=i; j--)System.out.print("* ");}System.out.println();}

* * ** **

(9) 菱形

我们把菱形切割一下,就转换成了打印两个等腰三角形的问题,一个是正立的,一个是倒立的。

第一个是正立的等腰三角形:

i 是 1 到 3

空格数 2, 1,0 ,所以 j 的范围是 i 到 2

星星数 1, 3, 5, 所以 j 的范围是 1 到 2i-1

第二个是倒立的等腰三角形:

i 是 1 到 2

空格数 1, 2, 所以 j 的范围是 1到 i

星星数 3,1,所以 j 的范围是 1 到 3+(i-1)*(-2) ,即 1 到 -2i+5

for(int i=1; i<=3; i++){for(int j=i; j<=2; j++){System.out.print(" ");}for(int j=1; j<=2*i-1; j++){System.out.print("*");}System.out.println();}for(int i=1;i<=2; i++){for(int j=1; j<=i; j++){System.out.print(" ");}for(int j=1; j<=-2*i+5; j++){System.out.print("*");}System.out.println();}

*************

可不可以不切割呢?不切割的话行数是1到5,左边的空格分别是2 ,1, 0, 1, 2,恐怕很难找到 j 跟 i的关系,可能很难处理,所以还是切割吧。

总结

问题的关键在于在每次外循环执行时控制j 的范围这个范围的距离将直接决定了内循环执行几次(或说打印几次),所谓范围的意思无非不就是 有个最小值和最大值,那么这个最小值和最大值的设定你可以有两个选择:要么固定点,要么是关于i的表达式。但无论你怎么做,目的只有一个,要让最大值和最小值的距离能够按照你希望的那样。就上面的例子具体而言,当你所需的距离正好是 i 的步长的时候,那么j的范围其中一端肯定是i,另一端你就找一个固定点;当你所需的距离不是i的步长,但是跟i有关系,那你就找到那个跟i的关系。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。