map和set是关联式容器,它们的底层的实现是都是红黑树,只是它们使用的模型不同,一个是key模型,一个key-value模型,之所以是关联性容器,是因为它们的数据存放是与其特性有关联性的,这里我们简单讲一下使用,因为其使用的方式和其他容器的区别不是很大。
set,因为是二叉树的结构,所以只有insert和erase,删除的是可以用迭代器来删也可以用值来删,如果要用迭代器,就要使用find函数,来查找,也可以用algorithm中的find函数,但是效率上,前者是logn后者是n,set容器的主要使用是判断一个值在不在,效率是很高的,但是不能修改。
map是key-value模型的使用方式,它拥有一个key值,和一个value值,但是它每一个节点的存储是由一个pair结构体来存放的,因此使用插入函数,必须使用 pair来插入。
也可以使用make_pair来进行构造。
map<int,int> m;
m.insert(pair<int,int>(1,1));
m.insert(make_pair(1,1));
输出,一般我们使用迭代器遍历
map<int,int>::iterator it = m.begin();
while(it != m.end())
{
cout<<it->first<<':'<<it->second<<endl;
it++;
}
map有一个operator[]的重载,返回的是map的引用的第二参数,即由key来访问value,它的底层是由insert来实现的,insert的使用是具有返回值的,它是一个pair<iterator,bool>的结构体,一个来说明是否插入成功,一个来返回这个节点的迭代器,因此再用map计数的时候,可以用【】来计数
for(auto e:words)
{
countmap[e]++;
}
因为访问key值,是插入的,那么插入后,初始化的value值是0,我们插入成功后++,进行修改,然后每次插入失败也++进行修改就可以计数。因此我们可以知道,map的【】可以进行插入,查找k对应的value,修改k对应的value。
mapped_type& operator[] (const key_type& k);
这里便是它的函数具体效用。
在set和map中,排序是以key来排序的,无论什么类型,它都会有自己的比大小方式。
multiset和multmap,这两个相比于普通的map和set而言,允许key 的冗余,而一般查找同一个key值的前后顺序是,先插入的先遍历,且是多个key的第一个,比如插入了多个3,那么第一个插入的3第一个遍历到,第二个插入那第二遍历到。