控制結構之迴圈:解決列印圖形問題
初入門的學習者,在迴圈結構常常會遇到打印出特定效果的圖形題。而據說,很多公司的面試題也包括了這樣的題目。那麼正確解決這類題目的思路是什麼呢?
題目舉例:
為平面圖案列印練習程式,分別程式設計完成如下圖案的列印:
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(); //保證迴圈結束後會換行;
}