C++ STL 速查:vector / map / unordered_map 技术 2026.10.18 技术

C++ STL 速查:vector / map / unordered_map

把最常用的容器操作、复杂度和几个容易记混的 API 放在一页里,方便写题和写小工具时查。

本文目录

这篇是给自己用的速查,不追求覆盖所有 API。示例默认使用 C++20。

vector

vector.cpp
#include <vector>
#include <algorithm>

std::vector<int> v = {3, 1, 2};

v.push_back(4);          // 末尾插入
v.emplace_back(5);       // 原地构造,通常比 push_back 少一次移动
v.pop_back();            // 删除末尾

v.reserve(100);          // 预分配容量,避免多次扩容
v.resize(10);            // 改变元素个数(会构造/析构)

std::sort(v.begin(), v.end());
auto it = std::lower_bound(v.begin(), v.end(), 3);

v.erase(v.begin());              // 删除第一个元素,O(n)
v.erase(v.begin() + 1, v.begin() + 3); // 删除区间 [1, 3)
操作 复杂度 备注
push_back / emplace_back 均摊 O(1) 扩容时可能 O(n)
pop_back O(1) 不释放容量
随机访问 v[i] O(1) 不检查越界
insert / erase 中间 O(n) 会移动后续元素
reserve(n) O(n) 只改容量,不改 size

map

std::map 是红黑树,按 key 有序,操作 O(log n)。

map.cpp
#include <map>
#include <string>

std::map<std::string, int> counts;

counts["apple"]++;              // 不存在时会插入默认值 0
counts.insert({"banana", 2});   // 已存在则不会覆盖
counts.emplace("cherry", 3);

auto it = counts.find("apple");
if (it != counts.end()) {
    it->second += 1;
}

for (const auto& [key, value] : counts) {
    // 按 key 升序
}

operator[] 会插入元素,查存在性时优先用 find 或 contains(C++20)。

unordered_map

哈希表,平均 O(1),不保证顺序。容易被卡哈希的题目里,可以换自定义哈希或改用 map。

unordered_map.cpp
#include <unordered_map>
#include <string>

std::unordered_map<std::string, int> index;
index.reserve(10000);   // 预分配桶,减少 rehash

index["key"] = 1;
if (auto it = index.find("key"); it != index.end()) {
    // it->second
}
容器 顺序 查找 插入 适用
map 按 key 有序 O(log n) O(log n) 需要有序遍历
unordered_map 无序 平均 O(1) 平均 O(1) 只做映射
vector 插入顺序 O(n) 末尾均摊 O(1) 小规模或需要连续内存

常用算法

algorithm.cpp
#include <algorithm>
#include <numeric>
#include <vector>

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

std::sort(v.begin(), v.end());
std::reverse(v.begin(), v.end());
std::sort(v.begin(), v.end(), std::greater<>{});

bool has_three = std::binary_search(v.begin(), v.end(), 3);
auto it = std::find(v.begin(), v.end(), 4);

int sum = std::accumulate(v.begin(), v.end(), 0);
int max_value = *std::max_element(v.begin(), v.end());

std::erase_if(v, [](int x) { return x % 2 == 0; }); // C++20

写算法题时,先想清楚「需不需要有序」和「需不需要随机访问」,再选容器。大多数性能问题不是容器选错,而是选错之后没有测。[1]


  1. 这句话有点绝对。更准确地说:先选一个语义正确的容器,再用 profiler 决定要不要换。 ↩︎

搜索本站

输入关键词开始搜索。支持中文分词,不支持拼音。