二重循環解題思路-顏羣

本文通過一道習題,講解做二重循環習題的思路:

 

題目:使用二重循環打印如下圖形:

wKiom1hrUy2CO8qvAAACddLybG0871.png-wh_50

分析:首先要明確我們需要打印的種類有:字符串*,字符串  (空格)。比如第一行,先打印了4個空格  ,然後打印了一個* 

我們分析一下每行的具體打印情況:

wKioL1hrU5Xg3TA7AAAHZloWmI4606.png-wh_50 

0行:先打印4個空格,然後打印1*

1行:先打印3個空格,然後打印3*

2行:先打印2個空格,然後打印5*

3行:先打印1個空格,然後打印7*

4行:先打印0個空格,然後打印9*

 

通過上面分析,我們不難發現,0, ”1”… ”4這些行數在重複,所以我們可以用外層循環控制行數(即打印第幾行)。在每行的內部,打印n個空格又是一個重複的過程,所以可以用內層循環來控制打印空格的個數。同理,在每行的內部,打印n*也是一個重複的過程,所以可以用內層循環來控制打印*的個數。即:用外層循環控制打印的行數,用兩個內層循環分別控制打印空格的個數和打印*的個數。還要注意,在把每行的空格和*打印完後,還需要換行。

即可得僞代碼:

public static void main(String[] args) {

int rows = 5;

for (int i = 0; i < 行數; i++) {

for (int j = 0; j < 空格的個數; j++) {

System.out.print(" ");

}

for (int j = 0; j < "*"的個數; j++) {

System.out.print("*");

}

System.out.println();//每行的空格和”*”打印完後,需要換行

}

}

 

我們在用i表示行數(第幾行),用j表示打印空格的個數,用k表示打印*的個數,可得下表:

wKiom1hrU6bxBNEbAAAHv_Mk5dU402.png-wh_50 

分析外層循環和內層循環的數學關係,可得:

i+j=4 j=4-i=(rows-1)-i, 即空格的個數等於:(當前行數-1)-i

k=2*i+1 ,即*的個數等於: 2*當前行數+1

現在,用計算後的關係式將僞代碼中的漢字替換,即可實現等腰三角形的打印:

public static void main(String[] args) throws Exception {

int rows = 5;

for (int i = 0; i < rows; i++) {

for (int j = 0; j < rows - i - 1; j++) {

System.out.print(" ");

}

for (int j = 0; j < 2 * i + 1; j++) {

System.out.print("*");

}

System.out.println();//每行的空格和”*”打印完後,需要換行

}

}

運行結果:

wKiom1hrU7ihv8FGAAACddLybG0736.png-wh_50 

 

思考:現將題目變爲:打印倒等腰三角形,如圖:

wKioL1hrU8nCp7PKAAACKllQMsQ717.png-wh_50 

該如何實現呢?

分析:對比“正等腰三角形”和“倒等腰三角形”,如下

wKiom1hrU9vi5w0RAAAP5M0HJ7Q889.png-wh_50 

不難發現,“倒等腰三角形”的第0行,就是“正等腰三角形”的最後一行;“倒等腰三角形”的第1行,就是“正等腰三角形”的倒數第二一行;“倒等腰三角形”的最後一行,就是“正等腰三角形”的第一行。即:把“正等腰三角形”的行數逆序輸出,就變成了“倒等腰三角形”。控制“正等腰三角形”行數的是外層循環for (int i = 0; i < rows; i++),將它逆序輸出,即改爲for (int i = rows-1; i>=0; i--),就實現了“倒等腰三角形”的打印,如下:

public static void main(String[] args) throws Exception {

int rows = 5;

// for (int i = 0; i < rows; i++)正等腰三角形

for (int i = rows - 1; i >= 0; i--) {// 正等腰三角形等行數逆序輸出

for (int j = 0; j < rows - i - 1; j++) {

System.out.print(" ");

}

for (int j = 0; j < 2 * i + 1; j++) {

System.out.print("*");

}

System.out.println();// 每行的空格和”*”打印完後,需要換行

}

}

運行結果:

wKiom1hrU_TSLGyvAAACKllQMsQ428.png-wh_50 

 

思考:現將題目變爲:打印菱形,如圖:

wKiom1hrVAvgfI_cAAADwR81oWE819.png-wh_50 

該如何實現呢?

分析:

將菱形上下拆開、一分爲二,即可分爲“正等腰三角形”和“到等腰三角形”,如圖:

wKiom1hrVCSx9WifAAAXrLYAemI934.png-wh_50 

因此,只需要先打印“正等腰三角形”,然後再打印“到等腰三角形”即可。需要注意,菱形的中間那一行,既是“正等腰三角形”的最後一行,同時也是“倒等腰三角形”的第一行。因此,在打印“正等腰三角形”時,不需要打印最後一行,如下:

public static void main(String[] args) throws Exception {

int rows = 5;

// 正等腰三角形

//for (int i = 0; i < rows; i++) {

for (int i = 0; i < rows-1; i++) {//for的第二個參數從row變爲row-1,即無需打印"正等腰三角形"的最後一行

for (int j = 0; j < rows - i - 1; j++) {

System.out.print(" ");

}

for (int j = 0; j < 2 * i + 1; j++) {

System.out.print("*");

}

System.out.println();// 每行的空格和”*”打印完後,需要換行

}

// 倒等腰三角形

for (int i = rows - 1; i >= 0; i--) {// 正等腰三角形等行數逆序輸出

for (int j = 0; j < rows - i - 1; j++) {

System.out.print(" ");

}

for (int j = 0; j < 2 * i + 1; j++) {

System.out.print("*");

}

System.out.println();// 每行的空格和”*”打印完後,需要換行

}

}

運行結果:

wKioL1hrVDqgv2ZuAAADwR81oWE748.png-wh_50 

 

思考:

現將題目變爲:打印空心菱形,如圖:

wKioL1hrVFDA0QTnAAADr9YylAg496.png-wh_50 

該如何實現呢?

分析:

 wKiom1hrVGnDmd8oAAAGiO4LoP4996.png-wh_50

實心菱形與空心菱形的區別是:空心菱形就是實心菱形的邊界,如下圖:

wKiom1hrVITBboviAAAMtrksQtU319.png-wh_50

即在打印“實心菱形”的“*”時,只需要把每一行“*”的開頭第一個“*”和結尾最後一個“*”打印出來,每行中間部分的“*”用空格替代即可。即對System.out.print("*");進行判斷,僞代碼如下:

if (開頭第一個*” 或 結尾最後一個“*) {

System.out.print("*");

} else {//即中間部分打印空格

System.out.print(" ");

}

完整代碼如下:

public static void main(String[] args) throws Exception {

int rows = 5;

// 正等腰三角形

for (int i = 0; i < rows; i++) {

for (int j = 0; j < rows - i - 1; j++) {

System.out.print(" ");

}

for (int j = 0; j < 2 * i + 1; j++) {

if (j == 0 || j == 2 * i) {//開頭第一個“*” 或 結尾最後一個“*”

System.out.print("*");

} else {//即中間部分打印空格

System.out.print(" ");

}

}

System.out.println();// 每行的空格和”*”打印完後,需要換行

}

// 倒等腰三角形

// for (int i = rows - 1; i >= 0; i--) {

for (int i = rows - 2; i >= 0; i--) {// “倒等腰三角形的第0行(即rows-1)不用打,直接從第1(rows-2)開始打印

for (int j = 0; j < rows - i - 1; j++) {

System.out.print(" ");

}

for (int j = 0; j < 2 * i + 1; j++) {

if (j == 0 || j == 2 * i) {//開頭第一個“*” 或 結尾最後一個“*”

System.out.print("*");

} else {//即中間部分打印空格

System.out.print(" ");

}

}

System.out.println();// 每行的空格和”*”打印完後,需要換行

}

}

運行結果:

wKioL1hrVOKRAfb6AAADr9YylAg796.png-wh_50 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章