? ? ? ? C++中有各种容器,其中有一种名为关联式容器,通过键值对的方式来记录对象,其中map和set就是经典的关联式容器,它们在数据的检索时的效率比序列式容器更高。
? ? ? ? 是一种表示具有一一对应关系的数据结构,一般包含 key 和 value 两个成员,key 表示键值,value 表示与 key 对应的信息,现实中的英汉互译字典就使用了键值对的结构。
? ? ? ? 在STL中,STL实现了两种不同结构的关联式容器:树型和哈希式结构,其中树型结构的关联式容器共有四种:map,set,multimap 和 multiset 四种。
? ? ? ??它们的共同点是底层采用的红黑树的结构,容器内是一种有序的结构。
? ? ? ? 相比于map,set 只用value作为键值对,可以视作 <value ,value> 构成的键值对,因此set插入元素的时候不用构造键值对。
? ? ? ? 此外,set 不允许重复的元素存在,可以使用set 进行去重。
? ? ? ? set底层默认采用从小到大排序,因而迭代set的元素能得到一个有序序列。
这些函数和迭代器的使用方式和之前的容器都一样,因此不再赘述。
这里面只有emplace和emplace_hint需要了解一下
emplace
这个函数返回一个 pair 类型,pair 的 first 为 iterator,seconde 为 bool 类型。
而且插入数据时不需要构建一个pair,内部会通过传入数据自动构建一个pair然后插入到set中。
不过当 set 中没有这个数据时,emplace 返回的 pair 的 first 是指向这个数据位置的迭代器,seconde 值为1,而有这个数据时,返回的 pair?的 first 是指向这个数据位置的迭代器,seconde 值为0;
#include<set>
#include<string>
#include<iostream>
using namespace std;
int main()
{
set<string> s;
pair<set<string>::iterator, bool> is = s.emplace("abcd");
cout << is.first->c_str() << " : " << is.second << endl;
is = s.emplace("abcd");
cout << is.first->c_str() << " : " << is.second << endl;
return 0;
}
?
emplace_hint
#include<set>
#include<string>
#include<iostream>
using namespace std;
int main()
{
set<string> s;
set<string>::iterator is = s.emplace_hint(s.begin(),"abcd");
cout << is->c_str() << endl;
is = s.emplace_hint(s.begin(),"abcd");
cout << is->c_str() << endl;
return 0;
}
?
而这个函数只会返回一个指向插入数据的迭代器,并且我们可以指定插入的位置。
不过由于set需要保持顺序,因此插入的数据不一定在我们指定的位置。?
find函数能够找到对应数据的迭代器。
count返回key对应值的个数,不过set的key和value相同,因此这里返回的不是0就是1.?
?
这个构造函数也和set一样,因此不再赘述
?这些函数也和之前容器类似,也不再赘述
?通过 [] 访问时,若key值存在,则得到value,不存在,则将key的value设置为默认值,然后插入到map中 。
通过 at 访问,若存在key值,则得到value,不存在则直接报异常
map的empalce和emplace_hint和set的一样,只不过形式不同
emplace
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
map<string, string> m;
pair<map<string, string>::iterator,bool> it = m.emplace("csdn", "https://blog.csdn.net/qq_37529913/article/details/118771777");
cout << it.first->first.c_str() << " : " << it.first->second.c_str()<<" : "<< it.second << endl;
return 0;
}
?同样的,存在则bool值为1,否则为0.
emplace_hint
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
map<string, string> m;
map<string, string>::iterator it = m.emplace_hint(m.begin(),"csdn","https://blog.csdn.net/qq_37529913/article/details/118771777");
cout << it->first.c_str() << " : " <<it->second.c_str()<< endl;
return 0;
}
这个函数也可以设置插入的位置,不过map为了保持顺序,可能插入的位置和设置的位置不同。
注意:
- multiset的底层储存的 <value,value>的键值对
- 它的插入接口只需要插入即可,不需要判断是否重复了
- 和set不同,它的key值可以重复
- 通过迭代器遍历,能得到有序的序列
- 元素不能修改
- 能够对数据进行排序
注意:该容器的key值可以重复,正因如此,该容器不能像map一样通过下标访问。