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