S SmartDocs
系列: C++ cpp 240 行 · 更新于 2026-04-03

iterators.cpp

C++/Part3_泛型與STL/Ch14_STL演算法與迭代器/iterators.cpp

// Ch14 — 迭代器(Iterators)示範
// 編譯:g++ -std=c++17 -Wall -o iterators iterators.cpp

#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <iterator>   // std::advance, std::next, std::prev, std::distance
#include <string>

// 輔助函式:印出分隔線
void section(const std::string& title) {
    std::cout << "\n===== " << title << " =====\n";
}

int main() {
    // ========================================================
    // 1. vector 的迭代器(Random Access Iterator)
    // ========================================================
    section("1. vector 迭代器基本操作");

    std::vector<int> v = {10, 20, 30, 40, 50};

    // 使用迭代器遍歷
    std::cout << "使用 iterator 遍歷 vector:";
    for (auto it = v.begin(); it != v.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << "\n";

    // 使用 range-based for(底層也是迭代器)
    std::cout << "使用 range-based for 遍歷:";
    for (int x : v) {
        std::cout << x << " ";
    }
    std::cout << "\n";

    // ========================================================
    // 2. const 迭代器(cbegin / cend)
    // ========================================================
    section("2. const 迭代器(唯讀)");

    std::cout << "使用 cbegin/cend(不能修改元素):";
    for (auto cit = v.cbegin(); cit != v.cend(); ++cit) {
        // *cit = 99;  // 編譯錯誤!const 迭代器不能修改
        std::cout << *cit << " ";
    }
    std::cout << "\n";

    // ========================================================
    // 3. 反向迭代器(rbegin / rend)
    // ========================================================
    section("3. 反向迭代器");

    std::cout << "使用 rbegin/rend 反向遍歷:";
    for (auto rit = v.rbegin(); rit != v.rend(); ++rit) {
        std::cout << *rit << " ";
    }
    std::cout << "\n";

    // const 反向迭代器
    std::cout << "使用 crbegin/crend(唯讀反向):";
    for (auto crit = v.crbegin(); crit != v.crend(); ++crit) {
        std::cout << *crit << " ";
    }
    std::cout << "\n";

    // ========================================================
    // 4. 迭代器輔助函式:advance, next, prev, distance
    // ========================================================
    section("4. advance / next / prev / distance");

    auto it = v.begin();
    std::cout << "v.begin() 指向:" << *it << "\n";

    // advance:將迭代器移動指定步數(會修改迭代器本身)
    std::advance(it, 2);
    std::cout << "advance(it, 2) 後指向:" << *it << "\n";

    // next:回傳往後移動 n 步的新迭代器(不修改原迭代器)
    auto it2 = std::next(it);
    std::cout << "next(it) 指向:" << *it2 << "(原 it 仍指向 " << *it << ")\n";

    auto it3 = std::next(it, 2);
    std::cout << "next(it, 2) 指向:" << *it3 << "\n";

    // prev:回傳往前移動 n 步的新迭代器
    auto it4 = std::prev(it);
    std::cout << "prev(it) 指向:" << *it4 << "\n";

    // distance:計算兩個迭代器之間的距離
    auto dist = std::distance(v.begin(), it);
    std::cout << "distance(v.begin(), it) = " << dist << "\n";

    // ========================================================
    // 5. list 的迭代器(Bidirectional Iterator)
    // ========================================================
    section("5. list 迭代器(雙向)");

    std::list<std::string> fruits = {"蘋果", "香蕉", "櫻桃", "芒果", "葡萄"};

    // 正向遍歷
    std::cout << "正向遍歷 list:";
    for (auto it = fruits.begin(); it != fruits.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << "\n";

    // 反向遍歷
    std::cout << "反向遍歷 list:";
    for (auto rit = fruits.rbegin(); rit != fruits.rend(); ++rit) {
        std::cout << *rit << " ";
    }
    std::cout << "\n";

    // list 是 Bidirectional Iterator,支援 ++ 和 --,但不支援 + n
    auto lit = fruits.begin();
    // lit = lit + 2;  // 編譯錯誤!Bidirectional Iterator 不支援 + n
    std::advance(lit, 2);  // 正確:advance 內部逐步前進
    std::cout << "advance(fruits.begin(), 2) 指向:" << *lit << "\n";

    // ========================================================
    // 6. map 的迭代器
    // ========================================================
    section("6. map 迭代器");

    std::map<std::string, int> scores = {
        {"Alice", 95},
        {"Bob", 87},
        {"Charlie", 92},
        {"Diana", 78}
    };

    // map 的迭代器指向 std::pair<const Key, Value>
    std::cout << "遍歷 map(按 key 排序):\n";
    for (auto it = scores.begin(); it != scores.end(); ++it) {
        std::cout << "  " << it->first << ":" << it->second << " 分\n";
    }

    // 使用結構化綁定(C++17)更簡潔
    std::cout << "使用結構化綁定遍歷 map:\n";
    for (const auto& [name, score] : scores) {
        std::cout << "  " << name << ":" << score << " 分\n";
    }

    // ========================================================
    // 7. 迭代器修改元素
    // ========================================================
    section("7. 透過迭代器修改元素");

    std::vector<int> nums = {1, 2, 3, 4, 5};
    std::cout << "原始 vector:";
    for (int x : nums) std::cout << x << " ";
    std::cout << "\n";

    // 使用迭代器將每個元素乘以 10
    for (auto it = nums.begin(); it != nums.end(); ++it) {
        *it *= 10;
    }

    std::cout << "修改後 vector:";
    for (int x : nums) std::cout << x << " ";
    std::cout << "\n";

    // ========================================================
    // 8. 迭代器 vs range-based for 的選擇
    // ========================================================
    section("8. 迭代器 vs range-based for");

    std::vector<int> data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    // 場景一:遍歷全部元素 → range-based for 更簡潔
    std::cout << "range-based for(遍歷全部):";
    for (int x : data) std::cout << x << " ";
    std::cout << "\n";

    // 場景二:只遍歷部分元素 → 需要迭代器
    std::cout << "iterator(只遍歷前 5 個):";
    for (auto it = data.begin(); it != data.begin() + 5; ++it) {
        std::cout << *it << " ";
    }
    std::cout << "\n";

    // 場景三:需要知道元素位置 → 迭代器 + distance
    std::cout << "找到第一個 > 5 的元素:";
    for (auto it = data.begin(); it != data.end(); ++it) {
        if (*it > 5) {
            std::cout << "值 = " << *it
                      << ",位置 = " << std::distance(data.begin(), it) << "\n";
            break;
        }
    }

    // 場景四:需要刪除元素 → 必須使用迭代器
    std::cout << "刪除所有偶數前:";
    for (int x : data) std::cout << x << " ";
    std::cout << "\n";

    for (auto it = data.begin(); it != data.end(); ) {
        if (*it % 2 == 0) {
            it = data.erase(it);  // erase 回傳下一個有效迭代器
        } else {
            ++it;
        }
    }

    std::cout << "刪除所有偶數後:";
    for (int x : data) std::cout << x << " ";
    std::cout << "\n";

    // ========================================================
    // 9. 插入迭代器(Insert Iterators)
    // ========================================================
    section("9. 插入迭代器");

    std::vector<int> src = {1, 2, 3, 4, 5};
    std::vector<int> dst;

    // back_inserter:在尾端插入
    std::copy(src.begin(), src.end(), std::back_inserter(dst));
    std::cout << "back_inserter 複製結果:";
    for (int x : dst) std::cout << x << " ";
    std::cout << "\n";

    // front_inserter 用於 deque、list(vector 不支援 push_front)
    std::list<int> lst;
    std::copy(src.begin(), src.end(), std::front_inserter(lst));
    std::cout << "front_inserter 複製到 list:";
    for (int x : lst) std::cout << x << " ";
    std::cout << "\n";

    // inserter:在指定位置插入
    std::vector<int> target = {100, 200, 300};
    std::copy(src.begin(), src.end(), std::inserter(target, target.begin() + 1));
    std::cout << "inserter 在位置 1 插入:";
    for (int x : target) std::cout << x << " ";
    std::cout << "\n";

    return 0;
}

相关文章