关联容器和顺序容器的区别为:关联容器通过键来存储和读取元素,而容器通过元素在容器中的顺序位置来访问和存储元素。两个基本的关联容器类型是map和set,map的元素以键-值对的形式存储:键用作元素在map中的索引,而值则表示存储的元素。set紧包含一个键,并有效地支持关于某个键是否存在的查询。
关联容器类型:
map 关联数组:元素通过键来存储和读取
set 大小可变的集合,支持通过键来实现快速读取
multimap 支持同一个键多次出现的map类型
multiset 支持同一个键多次出现的set类型
1.pair类型
pair类型也是一种简单的标准库类型,该类型定义在utility头文件中。
注意:pair不是一种容器类型!
pair类型定义的操作:
pair<T1,T2> p1; 创建一个空的pair对象,两个元素分别为T1,T2类型,采用值初始化
pair<T1,T2> p1<v1,v2>; 创建一个pair对象,两个元素类型分别为T1,T2,其中first成员初始化为v1,second成员初始化为v2
make_pair(v1,v2) 以v1,v2创建一个新的pair对象
p.first pair对象p的first成员
p.second pair对象P的second成员
输入:
james wife
david father
输出:
james wife
david father
2.关联容器概念介绍
关联容器共享大部分的顺序容器操作。关联容器不提供front,back,pop_front,pop_back,push_front,push_back。
顺序容器和关联容器公共操作包括以下:
*三种构造函数:
C<T> c;
C<T> c1(c2);
C<T> c1(b,e);
*begin,end,rbegin,rend操作;
*swap和赋值操作,但关联容器不支持assign操作;
*clear和erase操作,但关联容器的erase操作返回值为空;
*关于容器大小的操作,但关联容器不支持resize操作;
3.map类型
map的构造函数:
map<T1,T2> m; 创建一空的map对象m,值采用元素默认初始化;
map<T1,T2> m(m2); 创建m2的一个副本m;
map<T1,T2> m(b,e); 用迭代器b和e范围内的元素初始化m。
键类型的约束:
在使用关联容器时,它的键不仅有一个类型,而且还有一个相关的比较函数。默认情况下,标准库使用键类型定义的<操作符来比较。
所用的键类型的比较函数必须具有“严格弱排序”。
“容器元素根据键的次序排列”这一事实是一重要结论:在迭代器遍历关联容器时,我们可以确保按键的顺序访问元素,而与元素在容器中的存放位置无关!
此程序运行结果为:
111 i'm a student!
123 hello
185 world!
而非定义时的顺序:
123 hello
185 world!
111 i'm a student!
另外需要注意的一点是:map<t1,t2>::value_type类型的值为一pair类型,其first成员值为const map<t1,t2>::key_type类型,second成员值为map<t1,t2>::mapped_type类型。意即:map的键值不可修改,而值可以修改。
(1)给map添加元素
给map添加元素的实现方式有两种:通过insert成员实现,或者先用下标获取元素,然后给元素赋值,下面分别来介绍这两种方式。
(2)使用下标访问map对象
编写以下程序
map<string,int> str_int_map;
str_int_map["hello"]=123;
如同其它下标操作符,map中利用索引来获取元素值。如果该索引所对应的元素值已经在map中,则返回该元素值。只有所查找的值不存在时,map元素才为该键创建一新的元素,并将它插入map中。此时,所关联的值采用值初始化:类类型元素用默认构造函数初始化,内置类型元素则初始化为0;
在上面代码中,定义了map<string,int>类型对象 str_int_map;当执行str_int_map["hello"]时,先在str_int_map中查找是否存在键值为hello的键,如存在,则将该元素值改为123,否则,直接将该元素插入到str_int_map中,其对应的键值为hello。
(3)map的insert操作:
map容器提供的insert操作:
m.insert(e) e是一个用在m上的value_type类型的值,如果e.first不在m中,则插入一个值为e.second的新元素,
如果存在,则保持m不变。该函数返回一个pair类型对象,包含指向键为e.first元素的map迭代器以及
一个bool类型的对象,表示是否插入了该元素。
m.insert(beg,end) beg和end为标记元素范围的迭代器,其中的元素必须为value_type类型的键-值对,对于该范围内的所有元素
如果它的键在m中不存在,则将该键及其对应的值插入到m。返回值为void。
m.insert(iter,e) e是一个用在m上的value_type类型的值,如果e.first不在m中,则创建新元素,并以迭代器iter为起点
搜索新元素存储的位置。返回一个迭代器,指向m中具有指定键的元素。
程序运行结果为:
126
127
在实际应用中,如果我们想在map中插入元素时,若在键值存在的情况下不想改变其值,则可用insert,而在键值存在的情况下仍然想改变其值,则直接用键值下标操作来插入。
(4)从map对象中删除元素
m.erase(k) 删除m中键为k的元素,返回size_type类型值,表示删除的元素的个数。
m.erase(p) 删除m中迭代器p所指向的元素。返回void类型
m.erase(b,e) 删除m中迭代器b,e之间的元素。b,e要么相等,要么b在e的前面。返回void类型。
(5)查找并读取map中的元素
m.count(k) 返回m中k的出现次数
m.find(k) 如果m中存在按k索引的元素,则返回该元素的迭代器,如果不存在,则返回超出末端迭代器