版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/l773575310/article/details/79244209
C++ 学习笔记(11)关联容器、桶
参考书籍:《C++ Primer 5th》
API:关联容器
11.2 关联容器概述
11.2.2 关键字类型的要求
- 对于有序容器(map、multimap、set、multiset),关键字类型必须定义元素比较的方法。默认使用
<
运算符来比较。 - 在自定义
<
运算符时,必须定义为严格弱序(strict weak ordering):即小于等于,性质如下:
- 两个关键字不能同时小于等于对方。
- 如果k1小于等于k2,k2小于等于k3,那么k1必须小于等于k3。
- 如果两个关键字都不小于等于对方,那么这两个关键字等价。
- 设置比较类型时(multiset的第二个参数),应该是一种函数指针类型。
11.2.3 pair类型
11.3 关联容器操作
11.3.1 关联容器迭代器
- map的key是const的,set的key也是const的。
- 通常不对关联容器使用泛型算法,如果要,那就当作源序列(copy到一个序列)或者当作一个目的位置(调用inserter绑定插入器)。
11.3.2 添加元素
std::map<string, int> m; // 四种插入值的方法。
m.insert({ "a",1 });
m.insert(make_pair("b", 22));
m.insert(pair<string, int>("c", 333));
m.insert(map<string, int>::value_type("d", 4444));
- insert和emplace返回值是一个pair,frist成员是迭代器(指向给定关键字的元素),second是bool,表明元素是否成功插入(已在容器的不插入,返回false)。
11.3.3 删除元素
- erase的返回值是删除元素的数量,即对于可重复关键字容器,返回值可能大于1.
11.3.4 map的下标操作
11.3.5 访问元素
- multimap和multiset中多个元素相同关键字时,这些元素会相邻存储。
// 获取相同元素3种方法
multimap<int, string> m{ { 1,"a" },{ 2,"b" },{ 1,"c" },{ 1,"d" } };
// 方法1:使用find和count
int count = m.count(1); // 查找关键字是1的个数(3个)。
auto it = m.find(1); // 查找第一个关键字是1的迭代器。
for (size_t i = 0; i < count; ++i, ++it)
cout << it->second << endl; // 输出所有相同关键字的值:a c d
// 方法2:使用lower_bound(返回第一个不小于给定Key的迭代器)和upper_bound(返回第一个大于给定Key的迭代器)
for (auto beg = m.lower_bound(1), end = m.upper_bound(1); beg != end; ++beg)
cout << beg->second << endl;
// 方法3:使用euqal_range,得到一个pair,first等价lower_bound结果,second等价upper_bound结果。
for (auto pos = m.equal_range(1); pos.first != pos.second; ++pos.first)
cout << pos.first->second << endl;
11.4 无序容器
- 无序容器在存储上组织为一组桶,每个桶保存0个或多个元素,使用一个哈希函数将元素映射到桶。相同哈希值的元素会在同一个桶中。
- 计算元素的哈希值和在桶中搜索通常都是很快的操作。
- 不能直接定义关键字类型是自定义类型的无序容器,因为要使用哈希模版,所以必须同时提供自定义hash模版版本(需要提供函数代替==运算符(函数指针)和哈希值计算函数(函数指针))。