文章

multimap

std::multimap 是 C++ STL 中的关联容器,允许存储重复的键值对。它按键自动排序,并支持通过 equal_range() 查找所有具有相同键的元素。底层使用红黑树,提供 O(logN) 时间复杂度的查找、插入和删除操作。

multimap

multimap

std::multimap 是 C++ STL 中的关联容器,它与 std::map 类似,但允许多个相同的键(key)存在。它存储的是键值对(key-value),并且 key 不唯一,但 按 key 排序,每个 key 可以关联多个不同的 value。

基本特性

  • 键允许重复std::multimap 允许多个相同的 key 存在,因此每个 key 可以关联多个不同的 value。
  • 按 key 排序:与 std::map 一样,std::multimap 中的元素会根据 key 自动排序(默认升序),可以通过自定义比较函数来改变排序规则。
  • 底层实现std::multimap 使用平衡二叉树(如红黑树)实现,保证 O(logN) 的时间复杂度。
  • 元素访问:通过迭代器访问,不能随机访问元素(不像 std::vector)。

常用接口

定义方式

1
2
#include <map>
std::multimap<int, std::string> mmap;  // 定义一个 multimap,键为 int,值为 string

插入元素

1
2
3
mmap.insert({1, "apple"});    // 插入 key 为 1,值为 "apple"
mmap.insert({1, "banana"});   // 插入另一个 key 为 1 的元素,值为 "banana"
mmap.insert({2, "orange"});   // 插入 key 为 2,值为 "orange"

查找元素

1
2
3
4
auto it = mmap.find(1);   // 查找 key 为 1 的第一个匹配元素
if (it != mmap.end()) {
    std::cout << it->first << " => " << it->second << std::endl;  // 输出:1 => apple
}

查找所有匹配的元素

由于 multimap 允许重复的键,因此 find() 只会返回第一个匹配元素。如果需要查找所有匹配的元素,应该使用 equal_range()

1
2
3
4
auto range = mmap.equal_range(1);  // 查找所有 key 为 1 的元素
for (auto it = range.first; it != range.second; ++it) {
    std::cout << it->first << " => " << it->second << std::endl;  // 输出:1 => apple 1 => banana
}

删除元素

1
2
mmap.erase(1);  // 删除所有 key 为 1 的元素
mmap.erase(mmap.find(2));  // 删除 key 为 2 的第一个元素

获取元素个数

1
std::cout << "Number of elements with key 1: " << mmap.count(1) << std::endl;  // 输出:2

清空容器

1
mmap.clear();  // 清空 multimap

常用接口汇总

方法说明
insert()插入键值对,允许重复键
find()查找指定 key 的第一个匹配元素
equal_range()查找所有具有相同 key 的元素
count()返回指定 key 的元素个数
erase()删除指定 key 的元素(所有重复的会被删除)
clear()清空容器
begin()/end()返回容器的迭代器

使用示例

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 <iostream>
#include <map>

int main() {
    std::multimap<int, std::string> mmap;

    // 插入元素
    mmap.insert({1, "apple"});
    mmap.insert({1, "banana"});
    mmap.insert({2, "orange"});
    mmap.insert({2, "grape"});

    // 查找并输出所有 key 为 1 的元素
    auto range = mmap.equal_range(1);
    for (auto it = range.first; it != range.second; ++it) {
        std::cout << it->first << " => " << it->second << std::endl;
    }

    // 查找并输出所有 key 为 2 的元素
    range = mmap.equal_range(2);
    for (auto it = range.first; it != range.second; ++it) {
        std::cout << it->first << " => " << it->second << std::endl;
    }

    return 0;
}

输出

1
2
3
4
1 => apple
1 => banana
2 => orange
2 => grape

常见面试问题

multimapmap 的区别?

特性mapmultimap
键是否重复不允许重复键允许重复键
查找方式查找时返回第一个匹配元素查找时返回第一个匹配元素(可以通过 equal_range() 查找所有)
插入插入一个唯一的键值对插入相同键的多个值

如何删除指定 key 的所有元素?

使用 erase() 删除所有具有相同 key 的元素:

1
mmap.erase(1);  // 删除所有 key 为 1 的元素

如何按值排序 multimap

multimap 默认按 key 排序。如果想按 value 排序,可以将 multimap 转为 vector,然后使用 std::sort() 排序。

1
2
3
4
std::vector<std::pair<int, std::string>> vec(mmap.begin(), mmap.end());
std::sort(vec.begin(), vec.end(), [](const auto& a, const auto& b) {
    return a.second < b.second;  // 按 value 升序排序
});

拓展建议

  • 使用场景std::multimap 非常适用于需要存储一个键对应多个值的场景,例如:学生成绩(同一科目多次成绩)、订单商品(一个订单可能包含多个相同商品)。
  • 如果不需要重复的 key,可以使用 std::map,这会提供更高的性能和简化的逻辑。
本文由作者按照 CC BY 4.0 进行授权