顺序容器是按照它们在容器中的位置来顺序保存和访问的,而关联容器是按照关键字来保存和访问的。
1、初始化
关联容器分为两类:map和set.
a)、map是关键字-值对;set只有关键字。
map定义:
map<string,size_t> word_count = { {“Jon”,0},
{"Lucy",1},
{"Dicken",2} };
该定义将string映射到size_t,也就是说string是下标,size_t是值。
如:word_count[word];//返回下标为word的map容器的size_t的值。
b)、set定义:
map<string,size_t> word_count = { {“Jon”,0},
{"Lucy",1},
{"Dicken",2} };
新标准中可以列表初始化。
multimap和multiset:
关键字不唯一,即多个元素可以具有相同的关键字。
2、关键字类型
不是所有类型都可以用作关联容器的关键字。对于有序容器——map、multimap、set、multiset,关键字类型必须定义元素比较的方法(默认使用“<”关键字)。
使用自己定义的操作,在定义关联容器时需要提供比较操作类型。
如:
multiset<Sales_data, decltype(compareIsbn)*>
bookstore(compareIsbn);
其中decltype(compareIsbn)*定义了一个指向compareIsbn函数的指针类型,该函数定义了Sales_data中的元素比较的方法。函数定义如下:
bool compareIsbn(const Sales_data &lhs, const Sales_data &rhs)
{
return lhs.isbn() < rhs.isbn();
}
该函数对Sales_data中的成员函数.isbn()进行比较,返回一个布尔量表示两者的大小。
3、pair对象
map的成员是pair类对象。
pair与容器类似,是用来生成特定类型的模板。一个pair保存两个数据成员,它们类型可以不同。
如:
pair<string, size_t> word_count;//该pair保存一个string 和一个size_t
pair可以列表初始化,如:
pair<string, string> author{"James", "Joyce"};
定义了一个包含两个string的pair类对象author。
pair数据成员的获取:
pair.first;//返回pair第一个(公有)数据成员
pair.second;//返回pair第二个(公有)数据成员
4、关联容器操作
a)、对关联容器迭代器解引用,得到一个类型为容器的value_type的值的引用。
对map而言,value_type是一个pair类型,其first成员保存const的关键字,second成员保存值。
b)、和顺序容器一下,我们也可以通过迭代器遍历关联容器。
c)、增加元素:
c.insert(arge);
arge可以是对象(将此对象插入容器中)、迭代器范围(将迭代器范围内的所有元素插入容器)、迭代器和对象(将对象插入迭代器所指定的范围)。
d)、删除元素:
c.erase(arge);
arge可以为关键字(删除该关键字对应的所有对象)、迭代器(删除该迭代器指向的对象)、迭代器范围(删除迭代器范围所有元素)。
e)、下标操作:
set类型不支持下标操作。
map类型下标运算返回与下标关键字关联的值。注意,如果关键字不在map中,则会自动创建一个元素并插入到map中。
特别注意,对一个map进行下标操作时,会获得一个mapped_type对象(map类的值);但当解引用一个map迭代器时,得到一个value_type对象(pair)。
f)、访问元素
c.find(k);//返回第一个指向关键字k的迭代器
对map的下标操作可能会改变map(当下标关键字不在map中时),因此对于不想改变原有map内容的访问元素操作,我们应该使用find代替来下标操作。
c.count(k);//返回关键字等于k的元素数量
c.lower_bound(k);//返回一个迭代器,指向第一个关键字不小于k 的元素
c.upper_bound(k);//返回一个迭代器,指向第一个关键字大于k的元素
结合使用c.lower_bound(k)和c.upper_bound(k)可以获得一个迭代器范围,表示所有具有关键字k的元素范围。
c.equal_range(k);//返回一个pair,保存一对迭代器,分别指向第一个关键字不小于k 的元素和第一个关键字大于k的元素
5、无序容器
无序容器不使用比较运算符来组织元素,而是使用一个哈希函数和关键字类型的==运算符。