前面我们学习了pair模板类——《初识模板类pair》是为了本节学习map作准备。map作为有序关联式容器,其通过pair模板的形式存储元素,并根据key值(指pair中的first)进行自动排序,排序默认是升序,但我们也可以通过仿函数实现降序排序,值得注意的是,map的键值具有唯一性,不允许出现重复键值。

接下来我们通过代码来了解如何创建map容器:

#include<bits/stdc++.h>//万能头,以效率为中心 
#include<string>
#include<map>//包含头文件,养成好习惯 
/*map初始化 */
using namespace std;
void test()
{
map<int,int> mp1;//直接创建
map<int,int> mp2{{1,1,},{2,2},{3,3},{4,4},{5,5}} ;//初始化列表
map<int,int> mp3(mp2) ;//拷贝构造
map<int,int> mp4;
mp4=mp2;//'='运算符重载 
}
int main(){
    test();
    return 0;
}

代码成功编译,语法正确!

好学的读者并不满足于此,开头我们提到map容器是有序关联式容器,会根据key值自动排序且排序默认是升序,那我们怎么写仿函数来更改排序规则呢?

仿函数相关知识我就不细说了,这里主要通过实操更改map排序规则:

#include<bits/stdc++.h>//万能头,以效率为中心 
#include<string>
#include<map>//包含头文件,养成好习惯 
/*更改map自动排序规则(map默认是升序排序) */
struct mycmp//创建公共类 
{
bool operator()(int a,int b) const //重载函数调用运算符
{
return a>b;//自定义比较规则
}
};
using namespace std;
void test()
{
map<int ,string> mp1{{3,"Dptcpp"},{1,"编程问答"},{9,"计算机二级C语言"},{0,"数据结构教程"},{7,"Java教程"}};//建议这样初始化 ,直观具体
/*map会进行升序排序 */
cout << "map会进行升序排序:";
for(map<int,string>::iterator it = mp1.begin();it!=mp1.end();++it) //迭代器遍历 
{
cout << it->second << " ";
}
cout << '\n';
/*在容器创建之初就指定排序规则*/ 
map<int ,string,mycmp> mp2{{3,"Dptcpp"},{1,"编程问答"},{9,"计算机二级C语言"},{0,"数据结构教程"},{7,"Java教程"}};//第三个参数传入仿函数类型 
/*map按照仿函数降序排序 */
cout << "map会进行降序排序:";
for(map<int,string>::iterator it = mp2.begin();it!=mp2.end();++it) //迭代器遍历
{
cout << it->second << " ";
}
cout << '\n';
}
int main(){
    test();
    return 0;
}

编译结果如下:

仿函数更改map排序规则

仿函数创建分3步:创建公共类,重载函数调用运算符,然后自定义比较规则。通过仿函数我们更改了map的默认排序规则。

map有序关联式容器有很多成员函数,下表将介绍常用成员函数:

成员函数参数功能描述
operator[]const Key& key访问或插入元素。如果key不存在,会插入默认值并返回引用
insert()const value_type& value插入键值对。返回pair<iterator, bool>,bool表示是否插入成功
emplace()Args&&... args原地构造元素,避免拷贝。性能优于insert (C++11)
find()const Key& key查找指定key,返回迭代器。未找到返回end()
erase()const Key& key删除指定key的元素。返回删除的元素数量(0或1)
erase()iterator position删除迭代器指向的元素。返回下一个元素的迭代器
count()const Key& key返回指定key的数量。对于map总是返回0或1
contains()const Key& key检查是否包含指定key。返回bool (C++20)
empty()无参数检查map是否为空。返回bool
size()无参数返回map中元素的数量
clear()无参数清空map中的所有元素
begin()无参数返回指向第一个元素的迭代器
end()无参数返回指向末尾的迭代器
rbegin()无参数返回指向第一个元素的反向迭代器
rend()无参数返回指向末尾的反向迭代器
lower_bound()const Key& key返回第一个不小于key的元素的迭代器
upper_bound()const Key& key返回第一个大于key的元素的迭代器
equal_range()const Key& key返回包含所有key匹配元素的范围[pair<iterator, iterator>]
at()const Key& key访问指定key的元素,带边界检查。key不存在时抛出异常
swap()map& other交换两个map的内容


根据该成员函数表,我们简单操作一下map容器:初始化map并通过'[]'访问元素,然后调用size()查看map容器内元素总和。

#include<bits/stdc++.h>//万能头,以效率为中心 
#include<string>
#include<map>//包含头文件,养成好习惯 
/*简单操作map容器 */
using namespace std;
void test()
{
map<int ,string> mp{{0,"Dptcpp"},{1,"编程问答"},{2,"计算机二级C语言"},{3,"数据结构教程"},{4,"Java教程"}};//建议这样初始化 ,直观具体
/*通过'[]'key值遍历map容器*/
cout <<  "通过'[]'key值遍历map容器: ";
for(int i=0;i<5;++i) cout << mp[i]<< " ";
cout<<'\n';
cout << "此时map内总计有" << mp.size() << "个元素\n";
}
int main(){
    test();
    return 0;
}

编译结果为:

'[]'访问map元素

总结:map容器底层是靠pair模板类进行构造的,同时map是有序关联式容器,底层是红黑树,会自动按照key进行升序排列,我们也能通过仿函数更改其排序方式。

点赞(0)

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

Dotcpp在线编译      (登录可减少运行等待时间)