9. STL容器和算法

顺序容器

1. vector

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <vector>

// 基本操作
std::vector<int> vec = {1, 2, 3, 4, 5};
vec.push_back(6);                // 添加元素
vec.pop_back();                  // 移除最后一个元素
vec.insert(vec.begin() + 2, 10); // 在指定位置插入
vec.erase(vec.begin());         // 删除指定位置的元素

// 容量管理
vec.reserve(100);               // 预分配空间
vec.shrink_to_fit();           // 释放多余空间
std::cout << vec.capacity();    // 当前容量
std::cout << vec.size();       // 当前大小

// 访问元素
int first = vec.front();        // 第一个元素
int last = vec.back();         // 最后一个元素
int third = vec[2];            // 下标访问
int safe_access = vec.at(2);   // 带边界检查的访问

// 遍历
for (const auto& elem : vec) {
    std::cout << elem << " ";
}

2. deque

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#include <deque>

std::deque<int> dq = {1, 2, 3};

// 双端操作
dq.push_front(0);              // 前端添加
dq.push_back(4);              // 后端添加
dq.pop_front();               // 前端删除
dq.pop_back();               // 后端删除

// 随机访问
dq[2] = 10;                   // 修改元素
dq.insert(dq.begin() + 2, 5); // 插入元素
dq.erase(dq.end() - 1);      // 删除元素

// 大小操作
dq.resize(10);               // 调整大小
dq.shrink_to_fit();         // 优化内存使用

3. list和forward_list

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#include <list>
#include <forward_list>

// 双向链表
std::list<int> lst = {1, 2, 3, 4, 5};
lst.push_front(0);            // 前端添加
lst.push_back(6);            // 后端添加
lst.insert(++lst.begin(), 7); // 插入元素
lst.sort();                  // 排序
lst.reverse();              // 反转
lst.unique();               // 移除连续重复元素
lst.merge(other_list);      // 合并两个有序链表

// 单向链表
std::forward_list<int> flst = {1, 2, 3};
flst.push_front(0);          // 只能在前端添加
flst.insert_after(flst.begin(), 4); // 在指定位置之后插入
flst.erase_after(flst.begin());    // 删除指定位置之后的元素

关联容器

1. set和multiset

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#include <set>

// 集合
std::set<int> s = {3, 1, 4, 1, 5}; // 自动排序和去重
s.insert(2);                       // 插入元素
s.erase(1);                       // 删除元素
auto it = s.find(4);              // 查找元素
bool exists = s.count(3) > 0;     // 检查存在性

// 多重集合
std::multiset<int> ms = {1, 1, 2, 2, 3};
ms.insert(1);                     // 允许重复元素
auto range = ms.equal_range(1);   // 获取所有等于1的元素范围

2. map和multimap

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <map>

// 映射
std::map<std::string, int> scores = {
    {"Alice", 95},
    {"Bob", 89}
};

// 插入和访问
scores["Charlie"] = 92;           // 插入或更新
scores.insert({"David", 88});     // 插入
auto it = scores.find("Alice");   // 查找
scores.erase("Bob");             // 删除

// 遍历
for (const auto& [name, score] : scores) {
    std::cout << name << ": " << score << "\n";
}

// 多重映射
std::multimap<std::string, int> grades;
grades.insert({"Alice", 95});
grades.insert({"Alice", 92});     // 允许重复键

3. unordered容器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <unordered_set>
#include <unordered_map>

// 无序集合
std::unordered_set<int> us = {1, 2, 3, 4, 5};
us.insert(6);                    // O(1)平均时间复杂度
us.erase(1);
auto it = us.find(3);

// 无序映射
std::unordered_map<std::string, int> um = {
    {"one", 1},
    {"two", 2}
};
um["three"] = 3;
um.erase("one");

// 自定义类型作为键
struct Point {
    int x, y;
    bool operator==(const Point& other) const {
        return x == other.x && y == other.y;
    }
};

struct PointHash {
    size_t operator()(const Point& p) const {
        return std::hash<int>()(p.x) ^ std::hash<int>()(p.y);
    }
};

std::unordered_set<Point, PointHash> points;

容器适配器

1. stack

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include <stack>

std::stack<int> st;
st.push(1);                     // 压栈
st.push(2);
st.push(3);

while (!st.empty()) {
    std::cout << st.top() << " "; // 查看栈顶
    st.pop();                    // 出栈
}

// 自定义底层容器
std::stack<int, std::vector<int>> stack_vec;
std::stack<int, std::deque<int>> stack_deq;

2. queue和priority_queue

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <queue>

// 队列
std::queue<int> q;
q.push(1);                      // 入队
q.push(2);
q.push(3);

while (!q.empty()) {
    std::cout << q.front() << " "; // 查看队首
    q.pop();                      // 出队
}

// 优先队列
std::priority_queue<int> pq;              // 默认最大堆
std::priority_queue<int, std::vector<int>, 
                   std::greater<int>> min_pq;  // 最小堆

pq.push(3);
pq.push(1);
pq.push(4);

while (!pq.empty()) {
    std::cout << pq.top() << " ";  // 获取最大/最小元素
    pq.pop();
}

STL算法

1. 非修改序列算法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#include <algorithm>
#include <vector>

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

// 计数和查找
int count_2 = std::count(vec.begin(), vec.end(), 2);
auto it = std::find(vec.begin(), vec.end(), 4);
bool has_6 = std::any_of(vec.begin(), vec.end(), 
                        [](int x) { return x == 6; });

// 比较
bool is_sorted = std::is_sorted(vec.begin(), vec.end());
auto [min, max] = std::minmax_element(vec.begin(), vec.end());

// 搜索
auto it2 = std::search(vec.begin(), vec.end(),
                      pattern.begin(), pattern.end());

2. 修改序列算法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// 复制和移动
std::vector<int> dest(vec.size());
std::copy(vec.begin(), vec.end(), dest.begin());
std::move(vec.begin(), vec.end(), dest.begin());

// 转换
std::transform(vec.begin(), vec.end(), vec.begin(),
              [](int x) { return x * 2; });

// 删除和替换
auto new_end = std::remove(vec.begin(), vec.end(), 2);
vec.erase(new_end, vec.end());

std::replace(vec.begin(), vec.end(), 3, 30);

// 重排
std::reverse(vec.begin(), vec.end());
std::rotate(vec.begin(), vec.begin() + 2, vec.end());
std::shuffle(vec.begin(), vec.end(), std::random_device{});

3. 排序和相关算法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// 排序
std::sort(vec.begin(), vec.end());
std::sort(vec.begin(), vec.end(), std::greater<int>());

// 部分排序
std::partial_sort(vec.begin(), vec.begin() + 3, vec.end());
std::nth_element(vec.begin(), vec.begin() + 3, vec.end());

// 合并和集合操作
std::vector<int> merged;
std::merge(vec1.begin(), vec1.end(),
          vec2.begin(), vec2.end(),
          std::back_inserter(merged));

std::vector<int> intersection;
std::set_intersection(vec1.begin(), vec1.end(),
                    vec2.begin(), vec2.end(),
                    std::back_inserter(intersection));

4. 数值算法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <numeric>

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

// 累加
int sum = std::accumulate(vec.begin(), vec.end(), 0);
int product = std::accumulate(vec.begin(), vec.end(), 1,
                            std::multiplies<int>());

// 内积
std::vector<int> vec2 = {2, 3, 4, 5, 6};
int dot_product = std::inner_product(vec.begin(), vec.end(),
                                   vec2.begin(), 0);

// 部分和
std::vector<int> partial_sums;
std::partial_sum(vec.begin(), vec.end(),
                std::back_inserter(partial_sums));

// 相邻差
std::vector<int> differences;
std::adjacent_difference(vec.begin(), vec.end(),
                       std::back_inserter(differences));

57.12k 字
43篇文章