語法書 / AA 競程語法書 上冊 / 第六單元 / 陣列的基本遍歷

6.4 陣列的基本遍歷

把資料存進陣列之後,最常做的事就是遍歷(traverse):用迴圈把每一格走過一遍,邊走邊做事。陣列讓「讀入的順序」和「使用的順序」從此分家——資料存好之後,想正著走、倒著走、走幾遍都可以。這一節整理四個最基本的遍歷套路。

套路一:加總

long long sum = 0;                 // 總和可能超過 int,用 long long 保險
for (int i = 1; i <= n; i++) {
    sum += a[i];
}

套路二:找最大值(最小值同理)

int mx = a[1];                     // 拿第一個數當起點,比虛構的初始值安全
for (int i = 2; i <= n; i++) {
    if (a[i] > mx) mx = a[i];
}

第四單元學過「邊讀邊比」也能找最大值;差別在於存進陣列後,比完還能回頭使用每一個數

套路三:倒序輸出

for (int i = n; i >= 1; i--) {     // 倒著跑、倒著印
    cout << a[i] << ' ';
}

要印的第一個數,是最後一個讀進來的——這正是 6.2 解過的搬家的箱子

套路四:多遍掃描

有些題目一遍走不完。例如:把讀入的數列先印出偶數位置的數,再印出奇數位置的數(0-base:位置 0, 2, 4, \ldots 是偶數位置)——輸出順序跟讀入順序不同,輸入卻只能讀一次。存進陣列後,掃兩遍就解決:

for (int i = 0; i < n; i++)
    if (i % 2 == 0) cout << a[i] << '\n';    // 第一遍:偶數位置
for (int i = 0; i < n; i++)
    if (i % 2 == 1) cout << a[i] << '\n';    // 第二遍:奇數位置

範例程式碼

讀入 n 個數,輸出總和、最大值,再倒序印出整個數列:

#include <iostream>
using namespace std;

const int MAX_N = 100005;
int a[MAX_N];

int main() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }

    long long sum = 0;
    int mx = a[1];
    for (int i = 1; i <= n; i++) {
        sum += a[i];                   // 套路一:加總
        if (a[i] > mx) mx = a[i];      // 套路二:找最大
    }
    cout << "sum = " << sum << '\n';
    cout << "max = " << mx << '\n';

    for (int i = n; i >= 1; i--) {     // 套路三:倒序輸出
        cout << a[i] << ' ';
    }
    cout << '\n';

    return 0;
}

執行結果(輸入 53 9 2 9 5):

sum = 28
max = 9
5 9 2 9 3

動手試試看:把範例改成同時找出「最大值出現在第幾格」。提示:多記一個位置變數,跟 mx 一起更新;如果最大值出現不只一次,你的程式記到的是第一次還是最後一次?