关联容器
关联容器支持高效的关键字查找和访问。其中最主要的是两个容器map和set。map中元素是一些关键字-值对(键值对):关键字起到索引的作用,值则表示与索引相关联的容器。set中每个元素只包含一个关键字。标准库提供了8个关联容器,不同之处在于:是否是map或者set的变形;是否允许关键字的重复;是否有序保存元素。
//按关键字有序保存元素
map //关联数组:保存关键字-值对
set //关键字即值,即只保存关键字
multimap //关键字可重复出现的map
multiset //关键字可重复出现的set
//无序集合
unordered_map //用哈希函数组织的map
unordered_set //用哈希函数组织的set
unordered_multimap //哈希函数组织的map,关键字可重复出现
unordered_multiset //哈希函数组织的set,关键字可重复出现
关联容器概述
关联容器都支持
容器概览中的普通容器通用操作,但不支持顺序容器的位置相关操作(如push_front和push_back)却也有自己一些支持的特殊的操作和类型别名。关联容器不支持构造函数(
???)或者插入操作。
关联容器的迭代器都是双向的。
1、定义
每个关联容器都定义了一个默认构造函数;也可以将关联容器初始化为另一个同类型容器的拷贝;或者从一个范围值来初始化关联容器,只要这些值可以转化为容器所需的类型。
map<string,size_t> count;
map<string,int> cnt = {{"a",1},{"b",1}};//键值对{key,value}
set<string> s = {"a","b"};
1)添加元素
//v是value_type类型的对象;args用来构造一个对象
//对于map和set,只有当前元素的关键字不在c中才能插入元素。函数返回一个pair:指向具有指定关键字的元素的迭代器,指示是否成功插入的bool。
c. insert(v)
c.emplace(args)
c.insert(b, e) //b和e是迭代器,表示一个c::value_type类型值的范围
c.insert(il) //il是上述类型的一个列表值
//将迭代器p作为一个提示,指出从哪里开始搜索新元素应该存储的位置。返回一个迭代器,指向指向具有给定关键字的元素
c.insert(p, v)
c.emplace(p, args)
向set中添加元素(会检查关键字,存在相同的插入失败)
set2.insert({1,2,3,1,2,3});//set中三个元素
set2.insert(c.begin(),c.end());
向map中添加元素(会检查关键字,存在相同的插入失败)
word_cnt.insert({a,1});
word_cnt.insert(make_pair(word,1));
word_cnt.insert(pair<string,int>(word,1));
word_cnt.insert(map<string,size_t>::value_type (word,1))
向multimap和multiset中添加元素(不会检查关键字,插入一定成功)
a.insert({"a",1},{"a",2});//不检查关键字
c.erase(k) //从c中删除每个关键字为k的元素,返回一个size_type值,指出删除了多少个元素。
c.erase(p) //从c中删除迭代器p指出的真正元素,返回一个指向p之后一个元素的迭代器。
c.erase(b, e) //删除迭代器对b和e所表示的范围中的元素。
map和unorder_map容器提供了下标运算符和一个对应的at函数(at函数在发生越界非法访问的时候会抛出异常)。在使用下标运算符的过程中,如果没有对应的关键字不在map中,那么会为其创建一个元素并插入到map中,关联值将进行初始化。
c[k];
c.at(k);
//lower_bound,upper_bound不适用于无序容器
//下标和at只适用于非const的map和unordered_map
c.find(k) //返回第一个关键字为k的元素的迭代器,若不存在则返回尾后迭代器
c.count(k) //返回关键字等于k的数目
c.lower_bound(k) //返回一个迭代器,指向第一个关键字不小于k的元素
c.upper_bound(k) //返回一个迭代器,指向第一个关键字大于k的元素
c.equal_range(k) //返回一个迭代器pair,表示关键字等于k的元素的范围,若k不存在,pair的两个成员均等于c.end()
无序容器
无序容器并不使用比较运算符来组织元素,而是使用一个哈希函数和关键字类型的==运算符。通常可以使用一个无序容器来替换对应的有序容器,反之亦然。
无序容器在存储上组织为一组桶,每个桶保存0个或者多个元素。(听起来类似哈希表)因此无序容器的性能依赖于哈西函数的质量和桶的数量及其大小。
//桶接口
c.bucket_count() //正在使用桶的数目
c.max_bucket_count //容器能容纳的最多的桶的数量
c.bucket_size() //第n个桶中的元素个数
c.bucket(k) //关键字为k的元素在哪个桶中
//桶迭代
local_iterator //可以用来访问桶中元素的迭代器类型
const_local_iterator //桶迭代器的const版本
c.begin(n), c.end(n) //桶n的首元素迭代器和尾后迭代器
c.cbegin(n), c.cend(n) //const版本
//哈希策略
c.load_factor() //每个桶中平均元素数量,返回float值
c.max_load_factor() //维护桶的平均大小,返回float值
c.rehash(n) //重组存储
c.reserve(n) //重组存储