map map通常称为关联数组,每个元素key/value pair,每个key只能出现一次,不允许重复。而multimap是允许元素拥有相同的key。
map的特点
- 不可以直接改变元素的key,要修改元素的key,必须先移出该key的元素,然后插入新的key/value的元素。
- map中的元素是根据指定的比较函数按键值排序。
- 每个元素具有唯一的键值。
- 支持快速查找,查找的复杂度基本是log(N)。
- 快速插入,删除和修改value值。
//这里的value_type是pair,key_type是char,mapped_type(每个关键字关联的类型)是intmapfirst;
//默认构造函数
map first1;
//构建空的map容器,comp是key_compare类型。按照comp对key进行排序
/*comp的基本构建法
struct comp{
bool operator()(const char& lhs,const char &rhs)const
{ return lhs>rhs;
}
};
*/mapsecond(first);
//复制构造函数mapthird(second.begin(),second.end());
//范围构造函数
map third1(second.begin(),second.end());
map fourth(std::move(third));
//移动构造函数map fifth{{'a',1},{'b',2},{'c',3}};
//初始化列表进行初始化
map fifth1={{'a',1},{'b',2},{'c',3}};
map相关的函数
文章图片
pair类型
pair定义在utility中,一个pair保存两个数据成员,所以创建时,必须提供连个类型名。
//pair的初始化,这里假设第一个类型名为string,第二个类型名为int
pair p1;
//默认构造函数
pair p2(p1);
//复制构造函数
pair p3("aaaa",5);
//用给定值初始化pair p4=p3;
//利用赋值操作符
pair p5=make_pair("bbbb",4);
//利用make_pair//其他常用的操作
p.first//返回p的名为first的数据成员
p.second//返回p的名为second的数据成员
p.swap(p1);
//交换p和p1的frist和second
swap(p,p1);
set set是关键字的简单集合,元素依据其value自动排序,每个元素只出现一次,不允许重复。而multiset与它的唯一差别是元素可以重复。
set的特点
- set容器中的键值,不可直接修改,直接修改将会报纸set的内部结构(平衡二叉树)不平衡。
- 根据关键字可以快速读取数据。
- 每个元素都是唯一的。
//默认构造函数
set s1;
set s2;
//comp是key_compare类型,构造方法见map的初始化,若没有comp,默认是lessset s3(b,e)//b,e是std::set::iterator,将[b,e)之间的值赋给setset s4(s3);
//赋值构造函数
set s5(move(s4));
//移动构造函数
sets6{1,2,3,4,5};
//列表初始化
set的操作
文章图片
map和set的常问的问题
【C-C++易混知识点|C++容易忘记的知识点——map和set(六)】为何map和set的插入删除效率比用其他序列容器高?
因为对于关联容器来说,不需要做内存拷贝和内存移动。map和set容器内所有元素都是以节点的方式来存储,其节点结构和链表差不多,指向父节点和子节点。插入和删除就是指针换来换去,和内存移动没有关系。
为何每次insert之后,以前保存的iterator不会失效?
iterator这里就相当于指向节点的指针,内存没有变,指向内存的指针怎么会失效呢(当然被删除的那个元素本身已经失效了)。相对与vector来说,vector每次插入和删除,指针都有可能会失效,比如:当该内存块不够它扩容时,它会申请其它内存块,此时指针会失效!
当数据元素增多时(10000到20000个比较),map和set的插入和搜索速度变化如何?
STL的优势并不在于算法,而在于内存碎片。如果你需要经常自己去new一些节点,当节点特别多,而且进行频繁的删除和插入的时候,内存碎片就会存在,而STL采用自己的Allocator分配内存,以内存池的方式来管理这些内存,会大大减少内存碎片,从而会提升系统的整体性能。当时间运行很长时间后(例如后台服务程序),map的优势就会体现出来。从另外一个方面讲,使用map会大大降低你的编码难度,同时增加程序的可读性。学习STL map, STL set之数据结构基础看来是很有必要的。
推荐阅读
- C++修炼|C++ STL list、vector、deque、set、map、multimap、multiset、priority queue
- OpenCV|opencv (三十七)图像形态学——腐蚀
- 计算机视觉|OpenCV的简单使用教程与基本函数(C++版本)
- 《C++要笑着学》|【C++要笑着学】认识C++ | C++的发展史 | 学习方法建议
- 《C++要笑着学》|【C++要笑着学】缺省参数 | 函数重载
- 《C++要笑着学》|【C++要笑着学】内联函数 | 关键字auto | 范围for | 关键字 nullptr
- C/C++编程(libcurl学习(linux + cmake))
- C++一笑而过|C++学习之第十三天-移动语义与完成COW String类
- 指针|【发际线大作战】C++学习记录之用户自定义数据类型