11.1 使用关联容器
- 关联容器支持高效的关键字查找和访问,两个主要的关联容器类型是
map
和set
- 标准库提供8个关联容器,这8个容器的不同体现在三个维度上:
- 是一个
set
,或是一个map
- 要求不重复的关键字,或者允许重复关键字(允许重复关键字的容器名字汇总都有包含单词
multi
) - 按顺序保存元素,或无序保存(不保持关键字按照顺序存储的容器的名字都以单词
unordered
开头)
关联容器类型 | 特征 |
---|
map | 关联数组;保存关键字-值对 |
set | 关联字即值,即只保存关键字的容器 |
multimap | 关键字可重复出现的map |
multiset | 关键字可重复出现的set |
unordered_map | 用哈希函数组织的map |
unordered_set | 用哈希函数组织的set |
unordered_multimap | 哈希组织的map;关键字可以重复出现 |
unordered_multiset | 哈希组织的set;关键字可以重复出现 |
11.2 关联容器概述
- 对于有序容器
map
,multimap
,set
,multiset
,关键字类型必须定义元素比较的方法(见例子一)
bool compareIsbn(const Sales_data &lhs,const Sales_data &rhs){
return lhs.isbn()<rhs.isbn();
}
multiset<Sales_data,decltype(compareIsbn)*> bookstore(compareIsbn);
11.3 关联容器操作
类型别名 | 含义 |
---|
key_type | 此容器类型的关键字类型 |
mapped_type | 每个关键字关联的类型;只适用于map |
value_type | 对于set,与key_type相同;对于map,为pair<const key_type,mapped_type> |
- 当解引用一个关联容器的迭代器时,我们会得到一个
value_type
的值的引用(见例子一)
- 对于
map
来说,value_type
是pair
类型,其first
成员保存const
的关键字
- 当使用一个迭代器遍历一个
map
,multimap
,set
或multiset
时,迭代器按关键字升序遍历元素 - 对于不包含重复关键字的容器的
insert
操作和emplace
操作,返回一个pair
pair
的first
成员是一个迭代器,指向具有给定关键字的元素pair
的second
成员是一个bool
值,指出元素是插入成功还是已经存在于容器中(见例子三)
- 对允许重复关键字的容器,接受单个元素的
insert
操作返回一个指向新元素的迭代器。
- 这里无须返回一个
bool
值,因为insert
总是向这类容器中加入一个新元素
- 关联容器定义了三个版本的
erase
(见例子四) - 对一个
map
使用下标操作,其行为与数组或vector
上的下标操作很不相同:
- 使用一个不在容器中的关键字作为下标,会添加一个具有此关键字的元素到
map
中
- 如果一个
multimap
或multiset
中有多个元素就有给定关键字,则这些元素在容器中会相邻存储,因为multimap
和multiset
都是有序的(见例子六)
map<string,size_t> word_count;
string word;
while(cin>>word)
++word_count[word];
auto map_it=word_count.cbegin();
while(map_it!=word_count.cend()){
cout<<map_it->first<<" occurs "
<<map_it->second<<" tiems "<<endl;
++map_it;
}
c.insert(v)
c.emplace(args)
c.insert(b,e)
c.insert(il)
map<string,size_t> word_count;
string word;
while(cin>>word){
auto ret=word_count.insert({word,1});
if(!ret.second)
++ret.first->second;
}
c.erase(k)
c.erase(p)
c.erase(b,e)
c.find(k)
c.count(k)
string search_item("Alain de Botton");
auto entries=authors.count(search_item);
auto iter=authors.find(search_item);
while(entries){
cout<<iter->second<<endl;
++iter;
--entries;
}
注意:在map中查找元素是否存在,使用find
,而不是使用下标操作
11.4 无序容器
- 无序容器在存储上组织为一组桶,每个桶保存零个或多个元素