map是一个key_value的结构不允许出现重复的数据从上图中我们可以看出map由四部分组成Key就是map底层关键字的类型T是map底层value的类型map默认要求Key支持小于的比较如果不满足要求或者不满足相应的需要可以自行实现仿函数传给模板参数map底层存储数据的内存是从空间配置器申请的一般情况下我们都不需要传后两个参数map底层是用红黑树实现的增删插改效率是O(logN)迭代器遍历走的是中序所以是按key有序顺序遍历map的顺序是由key决定的map的底层直接存储了一个key_value的结构体——pair​pair是何方神圣呢我们一起来看一下——2.1 pair类型介绍map底层的红黑树节点中的数据使用pairKey, T存储键值对数据。​2.2 创建 map 对象explicit map (const key_compare comp key_compare(), const allocator_type alloc allocator_type());无参构造构造一个空的map对象template class InputIterator map (InputIterator first, InputIterator last,const key_compare comp key_compare(), const allocator_type allocator_type());迭代器区间构造map (const map x);拷贝构造map (initializer_listvalue_type ilinitializer list (5) initializer 列表构造创建一个空的map对象——最常用的方式代码语言javascriptAI代码解释void test_map1() { //创建一个空的map对象 //假设key的类型是stringT的类型是string/int mapstring, string map1; mapstring, int map2; }​一般情况下我们都不需要传剩余的两个参数2.3 插入键值对insert 方法在map中使用insert插入一个数据插入的数据也是一个pair假设现在我们要实现一个字典那我们该怎么插入一个pair数据呢​ok我们先来看看怎么构造一个pair对象——2.3.1 创建键值对pair 的构造代码语言javascriptAI代码解释void test_map2() { //创建一个pair对象有名对象 pairstring, string kv1(sort, 排序); //使用匿名对象 pairstring, string(left, 左边); //make_pair 一个函数模板给两个值会根据这两个值来构造一个类型 make_pair(right, 右边); }ok这样我们就可以实现插入的操作——代码语言javascriptAI代码解释void test_map2() { mapstring, string dict; //创建一个pair对象有名对象 pairstring, string kv1(sort, 排序); dict.insert(kv1); //使用匿名对象 dict.insert(pairstring, string(left, 左边)); //make_pair 一个函数模板给两个值会根据这两个值来构造一个类型 dict.insert(make_pair(right, 右边)); }插入结果​但是不知道有没有uu发现上面使用构造一个pair对象匿名对象make_pair进行插入的操作有点麻烦那我们就可以使用下面的方式代码语言javascriptAI代码解释dict.insert({ map,地图 });​注意这里不是initializer_list的构造如果是initializer_list的构造应该是pair的initializer_list代码语言javascriptAI代码解释dict.insert({ {string,字符串},{begin,开始} });//initializer_list构造注意key相同的数据无法插入map不允许key重复2.4 遍历键值对map的迭代器使用​迭代器遍历map​嗯为什么这里会报错ok这是因为这里无法直接进行打印为什么*it1的结果是一个pair类型的结构体pair不支持打印pair中有两个成员first和second如果直接打印该打印谁呢ok对于这种内部有多个成员组成的结构体类型我们可以使用下面的方法进行打印——代码语言javascriptAI代码解释while (it1 ! dict.end()) { cout (*it1).first : (*it1).second endl; it1; }但是我们更建议使用下面的方式进行打印——代码语言javascriptAI代码解释while (it1 ! dict.end()) { cout it1-first : it1-second endl; it1; }​范围for遍历方式一​方式二结构化绑定C17支持最推荐使用​对于这种方式我们可以这么理解​代码语言javascriptAI代码解释void test_map2() { mapstring, string dict; //创建一个pair对象有名对象 pairstring, string kv1(sort, 排序); dict.insert(kv1); //使用匿名对象 dict.insert(pairstring, string(left, 左边)); //make_pair 一个函数模板给两个值会根据这两个值来构造一个类型 dict.insert(make_pair(right, 右边)); //隐式类型转换 dict.insert({ map,地图 }); //initiaizer_list(pair的initiaizer_list) dict.insert({ {string,字符串},{begin,开始} }); //begin mapstring, string::iterator it1 dict.begin(); //end mapstring, string::iterator it2 dict.end(); //遍历方式一 while (it1 ! dict.end()) { cout (*it1).first : (*it1).second endl; it1; } //遍历方式二相较于1更推荐2 while (it1 ! dict.end()) { cout it1-first : it1-second endl; it1; } //方式三 for (auto e : dict)//*iterator是一个pair { cout e.first : e.second endl; } //方式四(最推荐使用) for (auto [k, v] : dict) { cout k : v endl; } }注意遍历的结果按key值升序排列从小到大2.5 删除键值对erase 操作iterator erase (const_iterator position);删除指定迭代器位置上的数据size_type erase (const key_type k);删除指定key数据删除只看key不看value成功删除返回1失败返回0iterator erase (const_iterator first, const_iterator last);删除[first,last)区间的数据代码语言javascriptAI代码解释mapstring, string::iterator it1 dict.begin(); //删除指定迭代器位置上的数据 dict.erase(it1); //删除指定key的数据存在就删否则什么都不做 dict.erase(map); //删除一段迭代器区间的数据 mapstring, string::iterator it2 dict.begin(); dict.erase(it2, dict.end());注意erase会有迭代器失效2.6 查找键值对find 操作iterator find (const key_type k);查找key查找到返回key所在的迭代器没有查找到返回end迭代器const_iterator find (const key_type k) const;查找const key查找到返回const key所在的const 迭代器没有查找到返回end迭代器代码语言javascriptAI代码解释void test_map3() { mapstring, string dict; dict.insert({ sort,排序 }); dict.insert({ string,字符串 }); dict.insert({ map,地图 }); dict.insert({ left,左边 }); dict.insert({ right,右边 }); dict.insert({ begin,开始 }); //查找 auto ret dict.find(right); if (ret ! dict.end()) { cout 找到了; } else cout 没有该单词; }运行结果​2.7 更新键对应的值通过前面的学习我们知道set是不能进行修改操作的但是map可以进行修改操作通过key来修改value​运行结果​ok那除了上面这种修改的方式还有没有其他更便捷更牛逼的修改方式呢肯定是有的2.7.1 map中的operator[ ] 重点在map中重载了 [ ] 运算符我们可以通过它来进行修改操作代码语言javascriptAI代码解释void test_map4() { string arr[] { 苹果, 西瓜, 苹果, 西瓜, 苹果, 苹果, 西瓜, 苹果, 香蕉, 苹果, 香蕉 }; mapstring, int countmap; for (auto e : arr) { countmap[e]; } for (auto [k, v]:countmap) { cout k : v endl; } }运行结果​这到底是咋做到了感觉有点小牛逼啊map::operator[ ] 的意思是 你给我key我找到对应的value​ok这里还有一个问题如果这个key是第一次出现怎么办这个key都不在map中怎么办呢countmap[ ](e);key已经在map中返回value的引用然后没有任何问题key不在map中第一次出现在map中呢怎么办这就说明[ ] 还有他的新功能