c++中如何使用multimap_c++支持重复键的关联容器用法【汇总】

multimap是C++中唯一原生支持重复键的有序关联容器,基于红黑树实现,允许insert相同key的多个值,禁用operator[],需用equal_range遍历匹配key的所有元素,erase(key)可一次性删除全部同key节点。

c++中如何使用multimap_c++支持重复键的关联容器用法【汇总】

multimap 是 C++ 标准库中唯一原生支持重复键的有序关联容器,它不强制键唯一,但要求键值对key 严格弱序排列(默认升序),底层通常基于红黑树实现。

如何声明和插入重复键的元素

map 不同,multimap 允许调用 insert() 多次插入相同 key 的不同值,且不会覆盖或报错。注意不能用 operator[] —— 它在 multimap 中被禁用,因为下标访问语义与“多值”冲突。

  • 必须使用 insert():支持 std::pairstd::make_pair 或花括号初始化
  • 推荐用 emplace() 避免临时对象拷贝(C++11 起)
  • 插入后容器自动按 key 排序,相同 key 的多个值按插入顺序(稳定排序)相邻存放
std::multimap mm;
mm.insert({1, "apple"});
mm.insert(std::make_pair(1, "banana"));  // 同 key,合法
mm.emplace(2, "cherry");                 // 更高效

如何遍历所有匹配 key 的元素

不能用 find() 直接取单个值——它只返回第一个匹配项的迭代器。要获取全部,必须用 equal_range(),它返回一个 std::pair,表示 [first, last) 区间内所有 key 相等的元素。

  • equal_range(key) 是最安全、最高效的批量查找方式
  • 若 key 不存在,返回的两个迭代器相等,循环体不执行
  • 不要混用 lower_bound() + upper_bound() 手动计算范围,易出错且可读性差
auto range = mm.equal_range(1);
for (auto it = range.first; it != range.second; ++it) {
    std::cout << it->first << ": " << it->second << "/n";
}

删除指定 key 的所有元素时要注意什么

erase(key) 会直接删除该 key 对应的所有节点,返回删除个数(size_t),这是最简洁的方式。但需警惕:若误用 erase(iterator) 只删一个,可能遗漏其余重复项。

Axiom

Axiom

Axiom是一个浏览器扩展,用于自动化重复任务和web抓取。

下载

立即学习C++免费学习笔记(深入)”;

  • mm.erase(1) 删除所有 key == 1 的元素,一步到位
  • 若只想删其中一个,先用 find() 获取单个迭代器再 erase(it)
  • 删除操作后,其他迭代器是否失效?—— 是的,被删节点的迭代器立即失效;未被删的仍有效(红黑树局部调整)

multimap 和 unordered_multimap 的关键区别

当性能成为瓶颈且不需要有序遍历时,应考虑 unordered_multimap:它用哈希表实现,平均 O(1) 插入/查找,但不保证任何顺序,且要求 key 类型提供 std::hashoperator==

  • multimap:有序、稳定、支持 lower_bound/upper_bound 等范围操作
  • unordered_multimap:无序、更快、但无法做“小于某 key 的所有元素”这类查询
  • 二者接口高度一致,替换成本低,但语义差异影响算法设计

真正容易被忽略的是:multimap 的“重复键”能力不是为替代数组而设的,它是为建模一对多关系(如学号→多门课程成绩)或需要按 key 分组检索的场景服务的。滥用会导致迭代开销陡增,尤其当某个 key 对应成百上千个 value 时,equal_range 返回的区间遍历本身就成了性能热点

https://www.php.cn/faq/2022637.html

发表回复

Your email address will not be published. Required fields are marked *