語法書 / AA 競程語法書 下冊 / 第十單元 / vector 的複製與比較

10.6 vector 的複製與比較

複製:一個等號搞定

上冊第六單元有個遺憾:陣列不能整個 a = b8.8 也提過 t = s; 是編譯錯誤,複製 C 字串得靠 strcpy)。vector 把這個遺憾補上了——= 直接用:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> a = {1, 2, 3};
    vector<int> b = a;                     // 完整複製一份
    b[0] = 99;                             // 改副本……
    cout << a[0] << ' ' << b[0] << '\n';   // 本尊毫髮無傷
    return 0;
}

執行結果:

1 99

注意 b = a完整複製:每個元素都抄一份過去(所以是 O(n) 的操作),之後兩個 vector 各自獨立、互不干擾——改 b 不會動到 a

複製是 O(n),這件事在把 vector 傳進函式時特別重要:寫 void f(vector<int> v) 的話,每次呼叫都整包複製一份(上冊 7.5 的傳值),大 vector 反覆傳就是效能炸彈。解法正是 7.5 教過的傳參考:

long long total(const vector<int>& v) {   // 傳參考不複製;const=保證不改動
    long long sum = 0;
    for (int i = 0; i < (int)v.size(); i++) {
        sum += v[i];
    }
    return sum;
}

要在函式裡修改原 vector,就拿掉 constvector<int>& v。細節在 12.3 會完整講;現階段先記住一條:大容器進函式,掛 &

比較:規則就是字典序

vector 也能直接用 ==<> 這些比較運算子,規則正是 8.9字典序——把「字元」換成「元素」,規則一字不改:逐格比較、第一個不同處定勝負、一路相同則先結束者小。8.9 的補充知識當時就說過字典序不是字串的專利,vector 正是最好的例子:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> a = {1, 2, 1, 2};
    vector<int> b = {1, 2, 3};
    cout << (a < b) << '\n';       // 索引 2 是第一個不同處:1 < 3,a 較小
    vector<int> c = {1, 2};
    cout << (c < b) << '\n';       // 前 2 格都一樣,c 先結束:c 較小
    vector<int> d = {1, 2, 3};
    cout << (b == d) << '\n';      // 長度相同、逐格相等:相等
    return 0;
}

執行結果:

1
1
1