16.4.6 关联容器

### 关联容器是对容器概念的另一个改进。

### 关联容器将值与键关联在一起,并使用键来查找值。

### 对于容器X,表达式X::value_type通常指出了存储在容器中的值类型。

### 对于关联容器,表达式X::key_type指出了键的类型

关联容器的优点:

  • 支持快速访问
  • 通常使用树实现
    • ### 和链表一样,因使用结点添加和删除数据项比较简单
    • ###    但相对于链表来说树的查找速度更快

与序列相似:

  • 允许插入新元素,但不能指定元素的插入位置

STL提供了4中关联容器:

  1. set
    •  键与值相同
    •     键是唯一的
  2. multiset
    •  键与值类型相同
    •     键可有多个值
    •     键是唯一的
  3. map
    •  键与值类型不同
    •     键只对应一个值
    •     键是唯一的
  4. 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对象:

  1. 并集set_union()
    •  接受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())); 
  2. 交集set_intersection():接口与并集同。
  3. 集合的差set_difference():接口与并集同。

两个有用的set方法:

  1. lower_bound():将键作为参数并返回一个迭代器,指向集合中第一个不小于键参数的成员
  2. 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对象,可以使用firstsecond成员来访问其两个部分:

###

pair<const int, string> item(213, "Los Angeles");
cout<<    item.first    <<    ' '    <<    item.second    <<    endl;

获取multimap对象的信息:

  1. 成员函数count():接受键作为参数,返回具有该键的元素数目
  2. 成员函数lower_bound()和upper_bound():将键作为参数,工作原理与处理set时相同
  3. 成员函数equal_range():用键作为参数,返回两个迭代器,表示的区间与该键的值的区间匹配:
    • ###    为返回两个值,该方法将它们封装在一个pair对象中
    • ###    pair对象的两个模板参数都是迭代器,first和second分别为begin_iterator和end_iterator

 

---------------------------

posted @ 2020-08-23 12:29  孱陵  阅读(105)  评论(0编辑  收藏  举报