C++unordered multimap
外观
概述[编辑 | 编辑源代码]
unordered_multimap是C++标准模板库(STL)中的无序关联容器,允许存储键值对(key-value pairs)且允许重复键。与`unordered_map`不同,其不要求键的唯一性,采用哈希表实现,提供平均O(1)时间复杂度的插入、删除和查找操作。
核心特性[编辑 | 编辑源代码]
- 无序性:元素顺序由哈希函数决定,非按键排序。
- 重复键支持:多个元素可拥有相同键。
- 哈希依赖:性能直接受哈希函数质量影响。
基本操作[编辑 | 编辑源代码]
头文件与声明[编辑 | 编辑源代码]
#include <unordered_map>
std::unordered_multimap<KeyType, ValueType> myMap;
插入元素[编辑 | 编辑源代码]
使用`insert()`或`emplace()`:
std::unordered_multimap<std::string, int> scores;
scores.insert({"Alice", 90});
scores.emplace("Bob", 85);
scores.insert({"Alice", 95}); // 允许重复键
访问元素[编辑 | 编辑源代码]
需使用迭代器或范围查找(因直接通过键访问可能不唯一):
auto range = scores.equal_range("Alice");
for (auto it = range.first; it != range.second; ++it) {
std::cout << it->first << ": " << it->second << '\n';
}
输出:
Alice: 90 Alice: 95
删除元素[编辑 | 编辑源代码]
通过迭代器或键删除:
scores.erase("Bob"); // 删除所有键为"Bob"的元素
实际案例[编辑 | 编辑源代码]
场景:学生成绩管理[编辑 | 编辑源代码]
存储学生多次考试成绩,允许同名学生(如重名情况):
std::unordered_multimap<std::string, int> gradebook;
gradebook.insert({"Zhang San", 88});
gradebook.insert({"Li Si", 92});
gradebook.insert({"Zhang San", 76}); // 同名不同人
// 查询所有"Zhang San"的成绩
auto zhangs = gradebook.equal_range("Zhang San");
for (auto it = zhangs.first; it != zhangs.second; ++it) {
std::cout << "Student: " << it->first << ", Score: " << it->second << '\n';
}
输出:
Student: Zhang San, Score: 88 Student: Zhang San, Score: 76
进阶特性[编辑 | 编辑源代码]
自定义哈希函数[编辑 | 编辑源代码]
需定义哈希结构体并重载`operator()`:
struct MyHash {
size_t operator()(const std::string& key) const {
return key.length(); // 简单示例:按字符串长度哈希
}
};
std::unordered_multimap<std::string, int, MyHash> customMap;
负载因子与重组[编辑 | 编辑源代码]
- 负载因子 = 元素数 / 桶数,通过`max_load_factor()`调整。
- 强制重组:`rehash(n)`设置桶数为`n`。
性能分析[编辑 | 编辑源代码]
与相似容器对比[编辑 | 编辑源代码]
特性 | unordered_multimap | unordered_map | multimap |
---|---|---|---|
键唯一性 | 否 | 是 | 否 |
排序方式 | 无序 | 无序 | 有序(红黑树) |
查找复杂度 | O(1) | O(1) | O(log n) |
数学基础[编辑 | 编辑源代码]
哈希表性能依赖于:
- 均匀哈希假设:键映射到桶的概率服从均匀分布,即(m为桶数)。
- 期望链长:(n为元素数)。
页面模块:Message box/ambox.css没有内容。
高负载因子可能导致哈希冲突激增,建议保持`max_load_factor()`在0.7~1.0之间。 |
总结[编辑 | 编辑源代码]
`unordered_multimap`适用于需要快速访问且允许键重复的场景,其性能优于有序容器(如`multimap`)但牺牲了顺序性。开发者需权衡需求选择合适容器。