16.4.6 关联容器
### 关联容器是对容器概念的另一个改进。
### 关联容器将值与键关联在一起,并使用键来查找值。
### 对于容器X,表达式X::value_type通常指出了存储在容器中的值类型。
### 对于关联容器,表达式X::key_type指出了键的类型
关联容器的优点:
- 支持快速访问
- 通常使用树实现
- ### 和链表一样,因使用结点添加和删除数据项比较简单
- ### 但相对于链表来说树的查找速度更快
与序列相似:
- 允许插入新元素,但不能指定元素的插入位置
STL提供了4中关联容器:
- set
- 键与值相同
- 键是唯一的
- multiset
- 键与值类型相同
- 键可有多个值
- 键是唯一的
- map
- 键与值类型不同
- 键只对应一个值
- 键是唯一的
- multimap
- 键与值类型不同
- 键可对应多个值
- 键是唯一的
### 前两种声明于头文件set(以前分别为set.h和multiset.h)
### 后两种在头文件map(以前分别为map.h和multimap.h)中声明
set容器:
- 是关联集合
- 可反转,可排序
- 使用模板参数指定存储的值类型: set<string> A; // a set of string objects
- ### 有第二个模板参数(可选),用于指示用来对键进行排序的比较函数或对象,默认使用模板 less< >
- ### 老式C++实现可能没有提供默认值,则必须显示指定
- set有一个将迭代器区间作为参数的构造函数:set<typename> object_name (begin_iterator, end_iterator);
数学为集合定义了一些标准操作:并集、交集和集合的差。STL提供了支持这些操作的算法。它们只是通用函数,而不是方法,
因此并非只能用于set对象:
- 并集set_union():
- 接受5个迭代器参数:
- 前两个定义第一个集合的区间
- 后两个定义第二个集合的区间
- 最后一个是输出迭代器,指出结果的输出位置
- 接受5个迭代器参数:
- 如:set_union(A.begin(), A.end(), B.begin(), B.end(), ostream_iterator<string, char> (cout, " "));
- 如果要将结果直接输出到集合,以上方法行不通:
- 原因一:关联集合将键看作常量,因而返回常量迭代器(不能改变值),它不能用作输出迭代器
- 原因二:set_union()函数的输出直接覆盖原有数据,对输出对象的空间有一定要求
- 解决办法:使用insert_iterator模板
- 过程将复制转换为了插入
- 模拟了输出迭代器概念
- 过程: set_union(A.begin(), A.end(), B.begin(), B.end(), insert_iterator<set<string>> (C, C.begin()));
- 交集set_intersection():接口与并集同。
- 集合的差set_difference():接口与并集同。
两个有用的set方法:
- lower_bound():将键作为参数并返回一个迭代器,指向集合中第一个不小于键参数的成员
- upper_bound():将键作为参数并返回一个迭代器,指向集合中第一个大于键参数的成员
程序中可使用using namesapce std;以简化表达式,从而避免使用过多的using声明或作用域运算符使得界面混乱
multimap容器:
- 与set相似,是可反转、经过排序的关联容器
- 键和值类型不同
- 同一个键可能与多个值相连
- 基本的multimap声明使用模板参数指定键的类型和存储的值类型:multimap<int, string> codes;
- ### 拥有第三个模板参数,指出用来对键进行排序的比较函数或对象。默认使用模板less < >,该模版
- ### 将键类型作为参数,老式C++实现可能要求显示指定该模板参数
### 为将信息结合在一起,,实际的值类型将键类型和数据类型结合为一对。为此,STL使用模板类pair<class T, class U>
### 将这两种值存储到一个对象中。
### 如假设keytype是键类型,而datatype是存储的数据类型,则值类型为pair<const keytype, datatype>
### 使用insert方法可以向multimap容器中插入创建的pair对象:
###
pair<const int, string> item(213, "Los Angeles"); // 创建区号-城市的键值对 codes.insert(item); // 插入该键值对
###
codes.insert(pair<const int, string> (213, "Los Angeles")); // 采用插入匿名对象的方式
### 对于pair对象,可以使用first和second成员来访问其两个部分:
###
pair<const int, string> item(213, "Los Angeles"); cout<< item.first << ' ' << item.second << endl;
获取multimap对象的信息:
- 成员函数count():接受键作为参数,返回具有该键的元素数目
- 成员函数lower_bound()和upper_bound():将键作为参数,工作原理与处理set时相同 成员函数equal_range():用键作为参数,返回两个迭代器,表示的区间与该键的值的区间匹配:
- ### 为返回两个值,该方法将它们封装在一个pair对象中
- ### pair对象的两个模板参数都是迭代器,first和second分别为begin_iterator和end_iterator
---------------------------