控制结构之循环:解决打印图形问题

初入门的学习者,在循环结构常常会遇到打印出特定效果的图形题。而据说,很多公司的面试题也包括了这样的题目。那么正确解决这类题目的思路是什么呢?


题目举例:

为平面图案打印练习程序,分别编程完成如下图案的打印:


1.1

*

* *

* **

* ** *

* ** * *

* ** * * *

* ** * * * *

 

1.2

* ** * *

* ** * * *

* ** * * * *

* ** * * * * *

* ** * * * * * *

1.3

* ** * *

* ** *

* **

* *

*

 

1.4

* ** * * 

  * * * * 

    * * *

      * *

        *

我建议的思路是先按照行再按照列,最后再解决特殊的变化情况。具体步骤如下:


(0)对行列进行标记。在图形边上标记出行数1,2,3……以及列数1,2,3……方便接下来找规律;


(1)解决行数问题。使用外层循环刻画行数,即for (int i = 1; i <= rowNumber; i++) 结构;


(2)解决列数问题。使用内层循环刻画列数,即for (int j = 1; j <= columnNumber; j++) 结构;


(3)解决行内变化问题。一般常常使用if-else语句来控制,即if ( 满足条件) {执行语句1;} else {执行语句2;} 结构;


(4)*有时候为了解决左侧空格问题,会在现有的j内层循环前面再加一个k内层循环,即for (int k = 1; k <= columnNumber; k++) 结构;但这不是一定的,可以看例子2。


那么我们从一个最简单的例子来看看这个是怎么做的。


编程完成如下图案的打印:

1.1

*

* *

* **

* ** *

* ** * *

* ** * * *

* ** * * * *


(0)上手的时候,为了得到关于行列的数字,我们首先对题目的行列进行标注;

1.1

* row1

* * row2

* ** row3

* ** * row4

* ** * * row5

* ** * * * row6

* ** * * * * row7

1234567(column)


接下来,我们就可以按照开始分析了。


(1)有7行,因此外循环需要走7遍。for (int i = 1; i <= 7; i++)


(2)每行的列数按照a[1]=1, a[2]=2, a[3]=3……的规律,得出a[n]=n;的数列规律(做打印图形题常常需要用到简单的高中数列分析的知识),换句话说,就是每行的总列数等于该行所在的第n行的函数。由于此处n=i,因此可以写出内循环 for (int j = 1; j <= i; j++) 

 

 由于这题比较简单,不存在复杂的行内变化,前面也不需要打空格,因此可以忽略步骤(3)(4),直接测试run了。

具体代码如下:

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


当然了,一般我们会遇到更难的题目,比如这样的:


2.3 请编码打印如下图形。

 

            *

          *  *

        *      *

      *           *

    *               *

      *          *

        *      *

          *  *

            *

其实仍然遵守以上所说的步骤,


(0)对行列进行标注;

            * 1

          *  * 2

        *      * 3

      *           * 4

    *               * 5

      *          * 6

        *      * 7

          *  * 8

            * 9

   123456789


此处,我们注意到第五行和第五列都是在中间,而且满足列数先增加后减少的规律。


(1)总行数很容易确定,是9行。不过此处考虑到从上到下是先增加后减少的,那么我们不如按照高中数学“分类讨论”的思想,先做上面5行,再做下面4行(或者先上4行,再下5行,都差不多)。写出for (int  i = 1; i <= 5; i++)


(2)列数问题。这个比较有意思,肉眼看上去会觉得第1行只有一列,但是此处要考虑到左侧的空格。


空格问题:空格如果全部在左侧的话,往往采用步骤(4),单独增加一个内循环来输出空格。但是此题空格出现在菱形的左侧和内部,属于和*混在一起的情况,不能使用独立的内循环来做,此处只能考虑用if-then选择结构。


因此列数实际上是每行最右边的星号所在位置。a[1]=5, a[2]=6, a[3]=7...显然a[n]=4+n,此处n=i(第i行)。那么我们可以写出for (int j = 1; j <= 4+i; j++);


(3)使用if-then选择结构输出菱形效果。这个图形完全是左右相对第5列进行轴对称的,因此我们依据这个轴来做分析就可以了。用数列来分析,b[1]=5, b[2]=4,6; b[3]=3, 7...得出b[n]=5+/-(n-1),也就是5+/-(i-1)就是需要打出星号的位置。那么我们可以写出

if (j==5+(i-1)||j==5-(i-1)) {
	System.out.print("*");
} else {
	System.out.print(" ");
}  //满足制定位置的条件就输出星号,其他都是空格;


下半部分的菱形也是按照相同的思路的,此处就不再赘述,参见以下完整的程序代码:

for (int i = 1; i <= 5; i++){
			for (int k = 1; k <= i+4; k++){
				if (k==(5+(i-1))||k==(5-(i-1))){
					System.out.print(" * ");
				} else{
					System.out.print("   ");
				}
			}
			System.out.println();
		}
		for (int i = 1; i <= 4; i++){
			for (int k = 1; k <= 9-i; k++){
				if (k==(5+(4-i))||k==(5-(4-i))){
					System.out.print(" * ");
				} else{
					System.out.print("   ");
				}
			}
			System.out.println(); //保证循环结束后会换行;
		}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值