【C++】关联式容器——map&set的使用(下)

简介: 【C++】关联式容器——map&set的使用(下)

3. 树形结构的关联式容器——map


map使用文档

e11871f71b97114b0760c6976056398a.png

  1. map是关联式容器它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元素
  2. 在map中key是排序和唯一标识的元素,value中存放的是与key相关的内容,key和value的类型不需要相同;在map中存放的类型不是key也不是value,而是一个pair对象,pair对象中的内容是key和value,在实现上是一个typedef,typedef pair<const key,value> value_type.
  1. 在map内部的元素存放位置严格按照key的强弱顺序排列,强弱顺序的比较规则又仿函数Compare控制,默认的仿函数是less
  1. map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序对元素进行直接迭代(即对map中的元素进行迭代时,可以得到一个有序的序列)
  1. map支持下表访问符[],即通过key访问到value
  1. map的底层是一个平衡搜索树(红黑树)


1. 默认成员函数

061b0320256a560ce96b852cbd8f592f.png

f66576e26daa4ee5e71bad7f240d7821.png

a85edc65509da7dd531f99a8e247da65.png

默认成员函数和set的用法非常相似,这里就不过多介绍了


2. 迭代器

25ef4ce8df199cc31cc7f79a51f8b8f7.png

迭代器的使用方式也是极其相似的,也就不多介绍了,有需要的朋友直接看文档即可


3. 容量与数据访问

函数原型 解释
bool empty() const 判断map是否为空,如果为空,返回true,否则返回false
size_type size() const 返回map中的元素个数,数据类型是size_type(unsigned int)
mapped_type& operator[] (const key_type& k); 返回key对应的value,这个value可以被修改

在map中有一个独特的数据访问方式:map中重载了operator[]操作符,可以通过key作为类似下标的方式访问到对应的value


对于这个特性,这里还有一种很新奇的的用法

/统计单词出现次数
vector<string> vs = {"apple", "banana", "apple","orange", "watermelon", "orange", "apple", "watermelon", "watermelon", "apple", "orange", "apple"};
map<string,int> m1;
for(const auto& e : vs)
{
  m1[e]++;
}


🙋当key不在map中时,通过operator获取对应value时会发生什么问题?

c0c5926e16b404e5dc1b4564c0e6082a.png

通过查看文档可知,如果使用的key不在map里面的时候,会自动调用insert函数插入一个key,然后使用value的默认构造创建一个值,构造一个pair对象,然后插入到map中。与其不同的是,at接口遇到这种情况的时候就会抛出异常。

这个原因也就是上面的新奇用法的原理。

void Test6()
{
    vector<string> vs = {"apple", "banana", "apple","orange", "watermelon", "orange", "apple", "watermelon", "watermelon", "apple", "orange", "apple"};
    map<string,int> m1;//默认构造
    for(const auto& e : vs)//统计次数的方式
    {
        m1[e]++;
    }
    map<string,int> m2(m1.begin(), m1.end());//迭代器区间
    map<string,int> m3(m1);//拷贝构造
    m1 = m3;//赋值重载
    cout << "---------------m1---------------" << endl;
    for(const auto& e : m1)
    {
        cout << e.first << ":" << e.second << endl;
    }
    cout << "---------------m2---------------" << endl;
    for(const auto& e : m2)
    {
        cout << e.first << ":" << e.second << endl;
    }
    cout << "---------------m3---------------" << endl;
    for(const auto& e : m3)
    {
        cout << e.first << ":" << e.second << endl;
    }
}

image-20230513154028887.png


4.数据修改

754d397770372f2bbbdee19d27682a08.png

数据的修改部分,只看接口的话,发现和set基本一致,用法之类的也都是一致的,没有什么特殊情况,所以也就不多说了。直接上示例:

void Test7()
{
    map<string, string> dict;
    dict.insert(make_pair("left", "左边"));
    dict.insert(make_pair("right", "右边"));
    dict.insert(make_pair("string", "字符串"));
    dict.insert(make_pair("sort", "排序"));
    for(const auto& e : dict)
    {
        cout << e.first << ":" << e.second << endl;
    }
    cout << "------after erase------" << endl;
    dict.erase("insert");
    for(const auto& e : dict)
    {
        cout << e.first << ":" << e.second << endl;
    }
    cout << "------after swap------" << endl;
    map<string, string> dict_swap;
    dict_swap.insert(make_pair("swap", "交换"));
    dict.swap(dict_swap);
    cout << "dict:" << endl;
    for(const auto& e : dict)
    {
        cout << e.first << ":" << e.second << endl;
    }
    cout << "dict_swap:" << endl;
    for(const auto& e : dict_swap)
    {
        cout << e.first << ":" << e.second << endl;
    }
    cout << "------after clear------" << endl;
    dict.clear();
    for(const auto& e : dict)
    {
        cout << e.first << ":" << e.second << endl;
    }
}


image-20230513155359566.png


5. 其他操作接口

022d8f35d853de662db9d4da276a689f.png

这里的操作接口与set的接口完全一样,就不过多赘述了。


<map>头文件中还包含了multimap这个容器,同样的multimap和map的用法完全基本相同,唯一的区别就是multimap允许重复的key值存在。和set与miltiset的关系一样,有需要的可以去对照上文的set和multiset。


本节完。。。

目录
打赏
0
0
0
0
3
分享
相关文章
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
29 2
|
11天前
|
【c++丨STL】map/multimap的使用
本文详细介绍了STL关联式容器中的`map`和`multimap`的使用方法。`map`基于红黑树实现,内部元素按键自动升序排列,存储键值对,支持通过键访问或修改值;而`multimap`允许存在重复键。文章从构造函数、迭代器、容量接口、元素访问接口、增删操作到其他操作接口全面解析了`map`的功能,并通过实例演示了如何用`map`统计字符串数组中各元素的出现次数。最后对比了`map`与`set`的区别,强调了`map`在处理键值关系时的优势。
114 73
|
12天前
|
【c++丨STL】set/multiset的使用
本文深入解析了STL中的`set`和`multiset`容器,二者均为关联式容器,底层基于红黑树实现。`set`支持唯一性元素存储并自动排序,适用于高效查找场景;`multiset`允许重复元素。两者均具备O(logN)的插入、删除与查找复杂度。文章详细介绍了构造函数、迭代器、容量接口、增删操作(如`insert`、`erase`)、查找统计(如`find`、`count`)及`multiset`特有的区间操作(如`lower_bound`、`upper_bound`、`equal_range`)。最后预告了`map`容器的学习,其作为键值对存储的关联式容器,同样基于红黑树,具有高效操作特性。
38 3
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
C++ 标准模板库(STL)提供了一组功能强大的容器类,用于存储和操作数据集合。不同的容器具有独特的特性和应用场景,因此选择合适的容器对于程序的性能和代码的可读性至关重要。对于刚接触 C++ 的开发者来说,了解这些容器的基础知识以及它们的特点是迈向高效编程的重要一步。本文将详细介绍 C++ 常用的容器,包括序列容器(`std::vector`、`std::array`、`std::list`、`std::deque`)、关联容器(`std::set`、`std::map`)和无序容器(`std::unordered_set`、`std::unordered_map`),全面解析它们的特点、用法
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
哈希表模拟封装unordered_map和unordered_set
哈希表模拟封装unordered_map和unordered_set
|
3月前
|
你对Collection中Set、List、Map理解?
你对Collection中Set、List、Map理解?
91 18
你对Collection中Set、List、Map理解?
只会“有序无序”?面试官嫌弃的List、Set、Map回答!
小米,一位热衷于技术分享的程序员,通过与朋友小林的对话,详细解析了Java面试中常见的List、Set、Map三者之间的区别,不仅涵盖了它们的基本特性,还深入探讨了各自的实现原理及应用场景,帮助面试者更好地准备相关问题。
84 20
【C++】unordered_map(set)
C++中的`unordered`容器(如`std::unordered_set`、`std::unordered_map`)基于哈希表实现,提供高效的查找、插入和删除操作。哈希表通过哈希函数将元素映射到特定的“桶”中,每个桶可存储一个或多个元素,以处理哈希冲突。主要组成部分包括哈希表、哈希函数、冲突处理机制、负载因子和再散列,以及迭代器。哈希函数用于计算元素的哈希值,冲突通过开链法解决,负载因子控制哈希表的扩展。迭代器支持遍历容器中的元素。`unordered_map`和`unordered_set`的插入、查找和删除操作在理想情况下时间复杂度为O(1),但在冲突较多时可能退化为O(n)。
49 5
【C++】map的模拟实现
C++中的`map`是STL中的一种关联容器,存储键值对且键唯一。`map`基于红黑树实现,自动按键排序,支持动态调整、复杂数据类型、丰富的成员函数及双向迭代器。插入、查找等操作保证了对数时间复杂度,适用于需要快速查找和有序存储的场景。
63 3

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等