本文通過一道習題,講解做二重循環習題的思路:
題目:使用二重循環打印如下圖形:
分析:首先要明確我們需要打印的種類有:字符串”*”,字符串” ”(空格)。比如第一行,先打印了4個空格” ”,然後打印了一個”*” 。
我們分析一下每行的具體打印情況:
第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表示打印”*”的個數,可得下表:
分析外層循環和內層循環的數學關係,可得:
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();//每行的空格和”*”打印完後,需要換行
}
}
運行結果:
思考:現將題目變爲:打印倒等腰三角形,如圖:
該如何實現呢?
分析:對比“正等腰三角形”和“倒等腰三角形”,如下
不難發現,“倒等腰三角形”的第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();// 每行的空格和”*”打印完後,需要換行
}
}
運行結果:
思考:現將題目變爲:打印菱形,如圖:
該如何實現呢?
分析:
將菱形上下拆開、一分爲二,即可分爲“正等腰三角形”和“到等腰三角形”,如圖:
因此,只需要先打印“正等腰三角形”,然後再打印“到等腰三角形”即可。需要注意,菱形的中間那一行,既是“正等腰三角形”的最後一行,同時也是“倒等腰三角形”的第一行。因此,在打印“正等腰三角形”時,不需要打印最後一行,如下:
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();// 每行的空格和”*”打印完後,需要換行
}
}
運行結果:
思考:
現將題目變爲:打印空心菱形,如圖:
該如何實現呢?
分析:
實心菱形與空心菱形的區別是:空心菱形就是實心菱形的邊界,如下圖:
即在打印“實心菱形”的“*”時,只需要把每一行“*”的開頭第一個“*”和結尾最後一個“*”打印出來,每行中間部分的“*”用空格替代即可。即對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();// 每行的空格和”*”打印完後,需要換行
}
}
運行結果: