【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。


本节完。。。

相关文章
|
6天前
|
存储 JavaScript 索引
js开发:请解释什么是ES6的Map和Set,以及它们与普通对象和数组的区别。
ES6引入了Map和Set数据结构。Map的键可以是任意类型且有序,与对象的字符串或符号键不同;Set存储唯一值,无重复。两者皆可迭代,支持for...of循环。Map有get、set、has、delete等方法,Set有add、delete、has方法。示例展示了Map和Set的基本操作。
17 3
|
8天前
|
设计模式 存储 Android开发
c++的学习之路:18、容器适配器与反向迭代器
c++的学习之路:18、容器适配器与反向迭代器
18 0
|
2天前
|
C++ 容器
STL—map容器
STL—map容器
|
6天前
|
存储 算法 程序员
C++从入门到精通:2.2.1标准库与STL容器算法深度解析
C++从入门到精通:2.2.1标准库与STL容器算法深度解析
|
6天前
|
存储 搜索推荐 C++
【C++高阶(二)】熟悉STL中的map和set --了解KV模型和pair结构
【C++高阶(二)】熟悉STL中的map和set --了解KV模型和pair结构
|
7天前
|
存储 自然语言处理 C++
c++的学习之路:25、map与set
c++的学习之路:25、map与set
10 0
|
13天前
|
C++ 容器
约瑟夫经典问题C++,STL容器queue解法
约瑟夫经典问题C++,STL容器queue解法
12 0
|
23小时前
|
存储 Java C++
【C++类和对象】探索static成员、友元以及内部类
【C++类和对象】探索static成员、友元以及内部类
|
23小时前
|
安全 程序员 编译器
【C++类和对象】初始化列表与隐式类型转换
【C++类和对象】初始化列表与隐式类型转换
|
23小时前
|
安全 编译器 C++
【C++类和对象】const成员函数及流插入提取
【C++类和对象】const成员函数及流插入提取