【C++】map详解(键值对的概念,与multimap的不同)

目录

00.引言

set 和 map 的区别

键值对的概念

01.map容器

主要特性

常用操作

主要用途

02.multimap容器 

特性

常用操作

用途


00.引言

set 和 map 的区别

set 和 map 都是C++标准模板库(STL)中的容器,它们的区别如下:

  • set 是一个集合容器,存储的是唯一的元素,元素本身就是它的值,且元素按照某种顺序进行存储。set 不允许存储重复元素,常用于去重场景。

  • map 是一种键值对容器,存储的是成对的数据(key-value pairs),其中键(key)是唯一的,值(value)可以重复。map 主要用于通过键快速访问对应的值。

键值对的概念

键值对(Key-Value Pair)是指一种数据结构,其中每个数据项都由两个部分组成:键(key)和值(value)。键是唯一的,通过键可以快速找到对应的值。键值对的应用广泛,特别是在映射、查找、统计和数据关联等场景中。

键值对的特性

        键是唯一的:在键值对中,每个键都是唯一的,不能有重复的键。

        值可以重复:虽然键是唯一的,但对应的值可以重复,即多个键可以映射到相同的值。

例如,在 map 容器中:

map<string, int> myMap;
myMap["apple"] = 10;  // "apple" 是键,10 是值
myMap["banana"] = 20;
myMap["apple"] = 20;  // 值可以被修改,也可以重复

01.map容器

map 是一种存储键值对的关联容器,底层通过红黑树实现,元素按照键进行排序,其提供了高效的插入、删除和查找操作。

主要特性

  • 键值对存储:每个元素由一个键和一个值组成,键通过某种排序规则存储,且键是唯一的。

  • 自动排序map 中的元素默认按照键的升序排序。可以使用自定义比较函数改变排序方式。

  • 查找效率map 使用红黑树(平衡二叉搜索树)作为底层结构,查找、插入和删除操作的时间复杂度为 O(log n)。

常用操作

1.插入元素:通过下标运算符 [] 或 insert 方法插入键值对:

map<string, int> myMap;
myMap["apple"] = 10;  // 插入键为 "apple",值为 10 的键值对
myMap.insert(make_pair("banana", 20));  // 使用 insert 插入键值对

要明白下标运算符 [] 是如何完成插入操作的,就要了解其底层逻辑,下图是官方的说明:

具体的说,如果 myMap[ k ] 此时元素k的键已存在,就会返回其对应的值的引用,既可以查看也可以修改;如果元素k的键不存在,则会插入一个元素k的新键,也会返回对应值的引用(默认为0)

2.查找元素:使用 find 方法查找键对应的值,返回指向键值对的迭代器,如果找不到对应的键,那么会返回一个指向 map 末尾的迭代器 map.end():

auto it = myMap.find("apple");
if (it != myMap.end()) {
    cout << it->first << ": " << it->second << endl;
}

3.删除元素:使用 erase 方法删除指定键的元素:

myMap.erase("apple");

4.遍历元素:可以通过迭代器遍历 map 中的所有键值对:

for (const auto& pair : myMap) {
    std::cout << pair.first << ": " << pair.second << std::endl;
}

主要用途

1.关联数组:将一个键映射到一个值,常用于模拟字典或关联数组。

2.统计频率:可以用来统计元素出现的次数,如统计单词的出现频率。

3.数据映射:适合用于需要快速查找键值对应关系的场景,比如用户 ID 与姓名的映射。

02.multimap容器 

在 C++ 标准模板库(STL)中,mapmultimap 存储的是键值对(key-value pairs),但它们之间有显著的区别:

键的唯一性:

map:键是唯一的,每个键只能对应一个值。如果插入一个已经存在的键,新值会替换旧值

multimap:允许键重复,即同一个键可以对应多个值。它适用于需要存储相同键的多个值的场景。

特性

multimap 适合用于存储一对多关系的数据。

键可重复multimap 中的键不必唯一,同一个键可以对应多个值。

自动排序multimapmap 一样,键默认是按升序自动排序的。

查找效率:和 map 一样,multimap 的查找、插入、删除操作的时间复杂度都是 O(log n)。

常用操作

1.插入操作:使用 insert 方法插入键值对,支持同一个键插入多个不同的值。

multimap<string, int> myMultimap;
myMultimap.insert(make_pair("apple", 10));
myMultimap.insert(make_pair("apple", 20));  // 允许相同键插入

注意:multimap 不能 使用 [] 运算符进行插入或访问。

这是因为 multimap 允许键重复,而 [] 运算符需要确保键是唯一的。[]map 中的行为是根据键查找对应的值,如果键不存在就插入一个新的键值对并返回引用,这种行为与 multimap 的多键特点冲突。

2.查找元素:

a. 使用 find 查找第一个匹配的键。

b. 使用 equal_range 方法查找某个键对应的所有值,返回一个范围(pair of iterators)。

auto range = myMultimap.equal_range("apple");
for (auto it = range.first; it != range.second; ++it) {
    cout << it->first << ": " << it->second << endl;
}

3.删除元素:使用 erase 方法删除某个键的所有值或单个键值对

   删除所有键值对:

myMultimap.erase("apple");  // 删除所有 "apple" 的键值对

   删除单个键值对:通过迭代器遍历删除

    auto it = myMultimap.find("apple");
    for (; it != myMultimap.end(); ++it) {
        if (it->second == 20) {
            myMultimap.erase(it);  // 通过迭代器删除该键值对
            break;
        }
    }

或者:通过范围迭代删除特定键值对

    // 获取 "apple" 键的范围
    auto range = myMultimap.equal_range("apple");

    // 在范围内查找并删除值为 20 的键值对
    for (auto it = range.first; it != range.second; ++it) {
        if (it->second == 20) {
            myMultimap.erase(it);  // 通过迭代器删除
            break;
        }
    }

4.遍历元素:可以像遍历 map 一样遍历 multimap 中的所有键值对。

for (const auto& pair : myMultimap) {
    std::cout << pair.first << ": " << pair.second << std::endl;
}

用途

1.一对多映射multimap 适合用于一对多的映射关系,比如在存储课程和学生名单时,一个课程可以有多个学生。

2.多重计数:当需要统计多个相同键对应不同值的情况时,multimap 是一种便捷的工具。

以上就是map和multimap的相关知识总结,欢迎在评论区留言,觉得这篇博客对你有帮助的,可以点赞收藏关注支持一波~😉

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谁在夜里看海.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值