4.6 巢狀迴圈

有些問題長得像表格:有好幾行、每一行裡又有好幾格(棋盤、九九乘法表都是)。一個迴圈搞不定,得把迴圈放進迴圈裡,一行一行、一格一格地處理。

迴圈可以放在迴圈裡面。每次外層迴圈執行一次,內層迴圈就會完整執行一遍。

怎麼想出雙層迴圈?

需要雙層迴圈的問題,通常有「每一個 A,都要對每一個 B 做一遍」的味道——就像背九九乘法表:2 的那一排要從 2 \times 1 背到 2 \times 9,背完才輪到 3 的那一排。想的時候把它拆成兩層:

  • 九九乘法表:外層跑每一列(乘數 1 到 9),內層在那一列裡跑每一欄(被乘數 1 到 9)。
  • 印一個 n 列的圖案:外層決定現在畫第幾列,內層畫出那一列的每一個字元。

口訣:外層管「第幾行」,內層管「這一行裡的每一格」。 每當外層走一步,內層就從頭到尾完整跑一遍。

範例程式碼

範例 1:九九乘法表

#include<iostream>
using namespace std;
int main() {
    for (int i = 1; i <= 9; i++) {      // 外層:控制行(乘數)
        for (int j = 1; j <= 9; j++) {  // 內層:控制列(被乘數)
            cout << i << "x" << j << "=" << (i*j) << "  ";
        }
        cout << "\n";                  // 一行結束後換行
    }

    return 0;
}

執行邏輯:

  • i = 1 時,j 從 1 迴圈到 9(輸出第一行)
  • i = 2 時,j 從 1 迴圈到 9(輸出第二行)
  • ...
  • i = 9 時,j 從 1 迴圈到 9(輸出第九行)

執行結果:

1x1=1  1x2=2  1x3=3  ... 1x9=9
2x1=2  2x2=4  2x3=6  ... 2x9=18
...
9x1=9  9x2=18 9x3=27 ... 9x9=81

追蹤外層前兩圈(看內層如何「整個跑完一遍」):

外層 i 內層 j 依序 這一圈印出
1 1, 2, 3, …, 9 1x1=1 1x2=2 … 1x9=9,然後換行
2 1, 2, 3, …, 9 2x1=2 2x2=4 … 2x9=18,然後換行

內層每被外層帶一次,就從 1 完整數到 9——所以總共印出 9 \times 9 = 81 格。這個「外層次數 × 內層次數」之後在 4.9 估計執行時間時很關鍵。

範例 2:印出直角三角形

#include<iostream>
using namespace std;
int main() {
    int n;
    cin >> n;           // 讀入三角形的高

    for (int i = 1; i <= n; i++) {      // 外層:控制行數
        for (int j = 1; j <= i; j++) {  // 內層:控制每行的星號數
            cout << "*";
        }
        cout << "\n";
    }

    return 0;
}

執行結果:(假設輸入為 5

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

動手試試看

  1. (暖身) 印出一個 n 列的正方形星號圖(每列都 n*)。
  2. (變化) 印出倒三角形:第一列 n*、第二列 n-1 個、…、最後一列 1 個。
  3. (想一想) 範例 2 的三角形,第 i 列印了 i 個星號,那整個圖案總共印了幾個星號?用第零單元學過的等差級數算算看。