关联容器在存储元素值的同时,还会为各元素额外再配备一个值(又称为“键”,其本质也是一个 C++基础数据类型或自定义类型的元素),它的功能是在使用关联式容器的过程中,如果已知目标元素的键的值,则直接通过该键就可以找到目标元素,而无需再通过遍历整个容器的方式。
弃用序列式容器,转而选用关联式容器存储元素,往往就是看中了关联式容器可以快速查找、读取或者删除所存储的元素,同时该类型容器插入元素的效率也比序列式容器高。
也就是说,使用关联式容器存储的元素,都是一个一个的“键值对”(<key,value>),这是和序列式容器最大的不同。除此之外,序列式容器中存储的元素默认都是未经过排序的,而使用关联式容器存储的元素,默认会根据各元素的键值的大小做升序排序。
map容器
作为关联式容器的一种,map容器存储的都是pair对象,也就是用pair类模板创建的键值对。其中,各个键值对的键和值可以是任意数据类型,包括C++基本数据类型(int、double等)、使用结构体或类自定义的类型。
通常情况下,map容器中存储的各个实值对都选用string字符串作为实值的类型。
与此同时,在使用map容器存储多个键值对时,该容器会自动根据各键值对的键的大小,按照既定的规则进行排序。使用map容器存储的各个键值对,键的值既不能重复也不能被修改。
map 容器存储的都是pair类型的键值对元素,更确切的说,该容器存储的都是pair<const K,T>类型(其中 K和T分别表示键和值的数据类型)的键值对元素。
示例:
#include<iostream>
#include<map>
using namespace std;
//键值不可重复
int main()
{
map<int, char> mp;// 键值 实值
mp[10] = 'A';
mp[100] = 'B';
mp[30] = 'C';
//根据键值来排序
map<int, char>::iterator ite=mp.begin();
while (ite != mp.end())
{
//ite->second = 'Q';// 可更改
cout << ite->first << " " << ite->second << endl;
//first是键值 不可修改 second是实值 可以修改
//ite->first = 1000; //不可以更改
ite++;
}
cout << endl;
pair<int, char> pa(250, 'b');//定义一个pair对象
mp.insert(pa);//插入一个pair对象
mp[100] = 'o';//直接对实值更改
ite = mp.begin();
while (ite != mp.end())
{
cout << ite->first << " " << ite->second << endl;
ite++;
}
ite = mp.find(100);//查找函数
cout << ite->first << " " << ite->second << endl;
return 0;
}
multimap容器
定义再<map>头文件中,和map容器唯一的不同在于,multimap容器中存储元素的键值可以重复
特别注意:当键值相同的时候 输出的排列顺序按添加的顺序排列
#include<iostream>
#include<map>
using namespace std;
//键值不可重复
//当键值相同的时候 输出的排列顺序按添加的顺序排列
int main()
{
multimap<int, char> mp;// 键值 实值
pair<int, char> pa1(200, 'b');//定义一个pair对象
mp.insert(pa1);//插入一个pair对象
pair<int, char> pa2(200, 'Q');//定义一个pair对象
mp.insert(pa2);//插入一个pair对象
pair<int, char> pa3(250, 'A');//定义一个pair对象
mp.insert(pa3);//插入一个pair对象
pair<int, char> pa4(190, 'a');//定义一个pair对象
mp.insert(pa4);//插入一个pair对象
map<int, char>::iterator ite = mp.begin();
while (ite != mp.end())
{
cout << ite->first << " " << ite->second << endl;
ite++;
}
return 0;
}
set容器
和 map容器不同,使用set容器存储的各个键值对,要求键key和值value必须相等。举个例子,如下有2组键值对数据:
{<'a',1>, <'b',2>, <'c', 3>}
{<'a','a'>,<'b','b'>, <'c','c'>}
显然,第一组数据中各键值对的键和值不相等,而第二组中各键值对的键和值对应相等。对于 set 容器来说,只能存储第2组键值对,而无法存储第一组键值对。
基于 set容器的这种特性,当使用set容器存储键值对时,只需要为其提供各键值对中的 value 值 (也就是key的值)即可。仍以存储上面第2组键值对为例,只需要为set容器提供{a','b','c},该容器即可成功将它们存储起来。
通过前面的学习我们知道,map容器都会自行根据键的大小对存储的键值对进行排序,set容器也会如此,只不过set容器中各键值对的键key和值value是相等的,根据key排序,也就等价为根据value排序。另外,使用set容器存储的各个元素的值必须各不相同,也就是不允许重复。
multimap容器
定义在<set>头文件中,和set容器唯一的不同在于,multiset容器中存储元素的值可以重复(一旦值重复,则意味着键也是重复的)。
示例:
#include<iostream>
#include<set>
using namespace std;
int main()
{
//set<int> st;// 有序 不可重复
multiset<int> st;
//st[10]=10;// set不能使用[ ]直接赋值
st.insert(1);
st.insert(2);
st.insert(3);
st.insert(4);
st.insert(2);//multiset中可重复
set<int>::iterator ite = st.begin();
while (ite != st.end())
{
//*ite = 10;//不可以修改
cout << *ite << endl;
ite++;
}
return 0;
}