一、基本原理
map是C++标准库提供的关联容器之一,保存的是键值对(key-value),我们可以通过key快速查找到其对应的value。map底层使用的数据结构是红黑树,因此在map中查找、添加或删除元素时间复杂度都是O(log(n))。此外,map中的元素还是有序的。
map使用场景:
现在假设有一个寝室501,寝室有4个学生,我们要用一种容器来保存这4个学生的学号和姓名,需求是我要通过学号来查找这个学号对应的姓名。
![](https://i-blog.csdnimg.cn/blog_migrate/fc63faa70e4698f40e02f6c885573433.png)
此时我们用一个map来保存,学号作为key,姓名作为value,一个学生的这两个信息作为map的一个元素pair(pair用法总结),这4个元素是按学号(key)升序存放的,我们可以通过学号来得到对应的姓名。
也许你会有这样的疑问,为什么要用关联容器呢,我用一个二维数组不是也一样能存放寝室4个学生的学号和姓名吗?
是的,存是可以存,但是操作的时间复杂度就不一样了,比如我知道学号"sc0303",我想查找对应的姓名,如果用map保存的,红黑树是一种自平衡的二叉搜索树,只需要O(log(n))的时间就能查到对应的姓名。如果用的二维数组保存的,需要从头遍历二维数组的第一列,需要O(n)的时间才能查到。这就是使用map的意义。
二、用法
map中的元素是一对对键值对,类型pair,用法可参考博客pair用法总结
初始化
map<T1,T2> 容器名; | T1、T2是类型名,可以是基本数据类型int、double等,也可以是类类型string等 |
---|---|
map<T1,T2> m1; | 创建一个名为m1的空map,key的类型为T1,value的类型为T2 |
map<T1,T2> m1{p1,p2……}; | m1中的元素被初始化为p1,p2……,p1、p2是pair类型 |
map<T1,T2> m1{ {key1,value1},{key2,value2}……}; | m1中的元素被初始化为 键值对{key1,value1},{key2,value2}…… |
map<T1,T2> m2(m1); | m2中包含和m1一样的元素 |
map<T1,T2> m2=m1; | m2中包含和m1一样的元素 |
程序示例:
pair<string, string> p1("sc0301","小杨"); // 方式一,创建一个pair名为p1
pair<string, string> p2 = make_pair("sc0302", "小马"); // 方式二,make_pair函数返回一个用"sc0302"和 "小马"初始化的pair
pair<string, string> p3("sc0303", "小王");
pair<string, string> p4("sc0304", "小何");
map<string, string> m1; // 创建一个空map
map<string, string> m2{
p1,p2,p3,p4 }; // 创建一个包含键值对p1、p2、p3、p4的map
map<string, string> m3{
{
"sc0301","小杨"},{
"sc0302", "小马"},{
"sc0303", "小王"},{
"sc0304", "小何"} }; // 效果同上一句
map<string, string> m4(m2); // 创建一个map,m4中包含和m2一样的元素
map<string, string> m5 = m2; // 创建一个map,m5中包含和m2一样的元素
访问元素
访问元素 | |
---|---|
T2 value = m1[key]; | 得到关键字key对应的值value |
m1.at(key); | 得到关键字key对应的值value |
*iter | 访问迭代器iter指向的元素 |
获取迭代器 | |
---|---|
m1.begin(); | 获取指向m1首元素的迭代器 |
m1.end(); | 获取指向m1尾元素的后一个位置的迭代器 |
m1.rbegin(); | 获取指向m1首元素的前一个位置的迭代器 |
m1.rend(); | 获取指向m1尾元素的迭代器 |
m1.cbegin(); m1.cend(); | 含义同上,但获取到的是const_iterator |
m1.crbegin(); m1.crend(); | 含义同上,但获取到的是const_iterator |
程序示例:
string p2_name = m2["sc0302"]; // 得到学号(关键字)"sc0302"对应的姓名(值)
string p3_name = m2.at("sc0303"); // 得到学号"sc0303"对应的姓名
map<string, string>::iterator it1 = m2.begin(); // 得到指向m2首元素的迭代器
map<string, string>::iterator it2 = m2