【C++ Primer Chapter 11 总结】关联容器
关联容器中的元素通过键来存储和检索。
顺序容器中的元素是按其在容器中的位置顺序存储和访问的。
-
map // 头文件 <map>
-
multimap
-
set // 头文件 <set>
-
multiset
-
unorder_map // 头文件 <unordered_map>
-
unorder_multimap
-
unorder_set // 头文件 <unordered_set>
-
unorder_multiset
1.对于有序容器(map、multimap、set和multiset),键类型必须定义一种比较元素的方法。
默认情况下,标准库使用键类型的<操作符来比较键。
可以提供自定义操作来代替键上的<操作符。指定的操作必须对键类型定义严格的 strict weak ordering。
2. 容器用于组织其元素的比较操作类型是该容器类型的一部分。
如果key类型没有定义<操作符,则需要额外提供比较操作类型。
在创建容器时,我们提供一个特殊的比较操作(必须与尖括号内指定的类型相同)作为容器类型的构造函数参数。
bool compareIsbn(const Sales_data &lhs, const Sales_data &rhs) {
return lhs.isbn() < rhs.isbn();
}
multiset<Sales_data, decltype(compareIsbn)*> bookstore(compareIsbn);
// 函数对象不能复制,没有引用,因此不能按值/引用传递,只能通过函数指针传递函数参数
// compareIsbn是函数类型
// 只有函数名作为实参传递时,才会隐式被转换为指针类型
// 因此第一个compareIsbn不会自动转换为函数指针,第二个compareIsbn会自动转换为函数指针
3.pair类型。
pair<Type1, Type2> p; pair<Type1, Type2> p(v1, v2); pair<Type1, Type2> p = {v1, v2}; make_pair(v1, v2); p.first p.second
4.查找元素。
1)find,2)count,3)[]操作,但是该操作会改变map,慎用!
c.find(key); // 返回第一个key的iterator c.count(key); // 返回 key的数量 c[key] // 如果key不存在,则会创建key,c[key] = 0
5. 无序容器使用hash函数和键类型的==操作符来组织它们的元素。
无序关联容器的key类型必须包含‘==’操作和hash<key_type>。所有内置类型以及指针,以及string和智能指针都定义了hash模板。
size_t hasher(const Sales_data &sd) { return hash<string>()(sd.isbn()); } bool eqOp(const Sales_data &lhs, const Sales_data &rhs) { return lhs.isbn() == rhs.isbn(); } using SD_multiset = unordered_multiset<Sales_data, decltype(hasher)*, decltype(eqOp)*>; SD_multiset bookstore(42, hasher, eqOp);
6.无序容器被组织为桶的集合,每个桶包含0个或多个元素。 这些容器使用散列函数将元素映射到桶。
要访问一个元素,容器首先计算元素的哈希代码,哈希代码告诉要搜索哪个桶。容器将具有给定散列值的所有元素放入同一个桶中。
如果容器允许多个元素具有一个给定的键,那么所有具有相同键的元素将在同一个桶中。