# 关联容器
set
:唯一键
的集合,按照键排序map
: 键值队的集合,按照键排序,键是唯一
的multiset
: 键的集合,按照键排序multimap
: 键值对的集合,按照键排序
# set
set
是关联容器,含有key
类型对象的已排序集,用比较函数 (compare
) 进行排序。搜索,移除和插入拥有对数复杂度,set 通常以红黑树实现
# 迭代器
begin/cbegin
: 返回指向起始的迭代器end/cend
: 返回指向末位的迭代器rbegin/crbegin
:返回指向起始的逆向迭代器rend/crend
: 返回指向末尾的逆向迭代器
# 容器
empty
: 检查容器是否为空size
: 返回容纳的元素数max_size
:返回可容纳的最大元素数
#include <iostream> | |
#include <set> | |
#include <algorithm> | |
using namespace std; | |
int main(void) | |
{ | |
// 创建关联容器 set | |
set<int> s{ 1,2,3,4,5,6 }; | |
// 使用 set 的迭代器,循环遍历 | |
for_each(s.cbegin(), s.cend(), [](int x) { cout << x << " "; }); | |
cout << endl; | |
// 让 bool 显示未 true 或 false | |
cout << boolalpha; | |
s.empty(); | |
cout << "s是否为空:" << s.empty() << endl; | |
cout << "s的元素个数:" << s.size() << endl; | |
cout << "s可理论容纳的最大数量:" << s.max_size() << endl; | |
cout << endl; | |
// 清除 s 内容 | |
s.clear(); | |
cout << "清除后s是否为空:" << s.empty() << endl; | |
// 插入元素 | |
s.insert(s.begin(), 99); | |
for_each(s.cbegin(), s.cend(), [](int x) { cout << x << " "; }); | |
cout << endl; | |
return 0; | |
} | |
/* | |
1 2 3 4 5 6 | |
s 是否为空:false | |
s 的元素个数:6 | |
s 可理论容纳的最大数量:576460752303423487 | |
清除后 s 是否为空:true | |
99 | |
*/ |
# 修改器
clear
: 清除内容insert
:插入元素或结点C++17
emplace
: 原位构造元素emplace_hint
: 使用提示原位构造元素erase
: 擦除元素- 参数:
pos
: 指向要移除的元素的迭代器first,last
:要移除的元素范围key
:要移除的元素键值x
: 任何能与键通透比较的类型的值,自带要移除的元素
#include <iostream> | |
#include <set> | |
using namespace std; | |
int main(void) | |
{ | |
set<int> c = { 1,2,3,4,1,2,3,4 }; | |
auto print = [&c] | |
{ | |
cout << "c={"; | |
for (int n : c) | |
{ | |
cout << n << " "; | |
} | |
cout <<"}"<< endl; | |
}; | |
print(); | |
cout << "移除所有奇数:" << endl; | |
for (auto it = c.begin(); it != c.end();) | |
{ | |
if (*it % 2 != 0) | |
{ | |
// 擦除首元素 | |
it = c.erase(it); | |
} | |
else | |
{ | |
++it; | |
} | |
} | |
print(); | |
cout << "移除1,移除个数" << c.erase(1) << endl; | |
cout << "移除2,移除个数" << c.erase(2) << endl; | |
cout << "移除2,移除个数" << c.erase(2) << endl; | |
print(); | |
return 0; | |
} | |
/* | |
c={1 2 3 4} | |
移除所有奇数: | |
c={2 4 } | |
移除 1,移除个数 0 | |
移除 2,移除个数 1 | |
移除 2,移除个数 0 | |
c={4 } | |
*/ |
swap
: 交换内容extract
: 从另一个容器释出结点C++17
解链含
position
所指向的结点并返回占有它的结点柄
若容器拥有元素而其关键等于 x,则从容器解链该元素并返回占有它的结点柄,否则返回空结点柄
参数:
* position: 指向此容器中的合法迭代器
* k: 鉴别要被释放出的结点的键
* x: 任何能与键通透比较的类型的值,鉴别要释放的结点extract
是set
带走仅移动对象的唯一方式
#include <iostream> | |
#include <algorithm> | |
#include <set> | |
using namespace std; | |
int main(void) | |
{ | |
set<int> cont{ 1,2,3 }; | |
auto print = [](const int& n) { cout << " " << n; }; | |
for_each(cont.begin(), cont.end(), print); | |
cout << endl; | |
//C++17. 解链含 position 所指向元素的结点柄返回占有它的结点柄 | |
auto nh = cont.extract(1); | |
// 对结点柄重新赋值 | |
nh.value() = 4; | |
for_each(cont.begin(), cont.end(), print); | |
cout << endl; | |
// 将 nh 结点柄插入尾部 | |
cont.insert(move(nh)); | |
for_each(cont.begin(), cont.end(), print); | |
cout << endl; | |
} | |
/* | |
1 2 3 | |
2 3 | |
2 3 4 | |
*/ |
merge
: 从另一个容器接合结点C++17
#include <iostream> | |
#include <set> | |
using namespace std; | |
template <class Os,class K> | |
Os& operator<<(Os& os, const std::set<K>& v) | |
{ | |
// 求出 set 的大小 | |
os << '[' << v.size() << "] {"; | |
bool o{}; | |
for (const auto& e : v) | |
{ | |
// 判断是否为空决定是,还是空 | |
os << (o ? ", " : (o = 1, " ")) << e; | |
} | |
return os << " }\n"; | |
} | |
int main(void) | |
{ | |
set<char> | |
p{'C','B','B','A' }, | |
q{ 'E','D','E','C' }; | |
cout << "p: " << p << "q: " << q; | |
// 对 set 进行合并 | |
p.merge(q); | |
// 合并自动去重 | |
//q 留下重复的部分 | |
cout << "p.merge(q):" << p << "q: " << q; | |
} | |
/* | |
p: [3] { A, B, C } | |
q: [3] { C, D, E } | |
p.merge(q):[5] { A, B, C, D, E } | |
q: [1] { C } | |
*/ |
# 查找
count
: 返回匹配特定键的元素数量find
: 遵照带有特定键的元素contains
:检查容器是否含有带特定键的元素equal_range
: 返回匹配特定键的元素范围lower_bound
: 返回指向首个不小于给定键的元素迭代器upper_bound
: 返回指向首个大于给定键的元素的迭代器
# 观察器
key_comp
: 返回用于比较键的函数value_comp
:返回用于在value_type
类型的对象中比较键的函数
# multiset
multiset 是含有 key 类型对象有序集的容器,与 set 不同,它允许
多个key
拥有等价的值,用关键比较函数 Compare 进行排序,搜索,插入和移除操作拥有对数复杂度其用法与set相同
# map
有序键值队容器,它的元素的键是惟一的。
# 元素访问
- at: 访问指定的元素,同时进行越界检查
- operator []: 访问或插入指定的元素
#include <iostream> | |
#include <map> | |
#include <string> | |
using namespace std; | |
// 输出键值队 map | |
auto print = [](auto const comment, auto const& map) | |
{ | |
cout << comment << "{"; | |
for (const auto& pair : map) | |
{ | |
cout << "{" << pair.first << ":" << pair.second << "}"; | |
} | |
cout << endl; | |
}; | |
int main() | |
{ | |
map<char,int> letter_counts { {'a',27},{'b',3},{'c',1} }; | |
print("letter_counts初始状态下包含:", letter_counts); | |
letter_counts['b'] = 42; | |
letter_counts['x'] = 9; | |
print("修改后的值", letter_counts); | |
// 统计每个单词出现的次数 | |
map<string, int> word_map; | |
for (const auto& w : { "this","sentence","is","not","a","sentence","this","sentence","is","a","hoax" }) | |
{ | |
++word_map[w]; | |
} | |
word_map["that"]; // 插入对 {"that",0} | |
print("输出map:",word_map); | |
} |
# 迭代器
- begin/cbegin:返回指向起始的迭代器
- end/cend: 返回指向末尾的迭代器
- rbegin/crbegin: 返回指向起始的逆向迭代器
- rend/crend: 返回指向末尾的逆向迭代器
# 容器
- empty: 检查容器是否为空
- size: 返回容器的元素数
- max_size: 返回可容纳的最大元素数
# 修改器
- clear: 清楚内容
- insert: 插入元素或结点
- insert_or_assign: 插入元素,或若键已存在赋值给当前元素
- emplace: 原位构造元素
- emplace_hint:使用提示原位构造元素
- try_emplace: 若键不存在则原位插入,若键存在则不做任何事情
- erase: 擦除元素
- swap: 交换内容
- extract:从另一个容器释出结点
- merge: 从另一容器接合结点
# 查找
- count: 返回匹配特定键的元素数量
- find: 寻找带有特定键的元素
- contains: 检查容器是否含有带特定键的元素
- equal_range: 返回匹配特定键的元素范围
- lower_bound: 返回指向首个不小于给定键的元素的迭代器
- upper_bound: 返回指向首个大小给定键的元素的迭代器
# 观察器
- key_comp: 返回用于比较键的函数
- value_comp: 返回用于在 value_type 类型的对象中比较键的函数
#include <iostream> | |
#include <map> | |
#include <string> | |
using namespace std; | |
// 输出键值队 map | |
auto print_map = [](auto const comment, map<string,int>&map) | |
{ | |
cout << comment ; | |
//C++11 方案 | |
for (const auto& pair : map) | |
{ | |
cout << "{" << pair.first << ":" << pair.second << "}"; | |
} | |
cout << endl; | |
}; | |
int main() | |
{ | |
map<string, int> m{ {"cpu",10},{"GPU",15},{"RAM",20} }; | |
print_map("初始map:", m); | |
// 以不存在的键执行插入操作 | |
m["SSD"] = 30; | |
print_map("插入不存在的:", m); | |
// 移除 GPU | |
m.erase("GPU"); | |
print_map("移除后:", m); | |
// 条件移除 | |
erase_if(m, [](const auto& pair) { return pair.second > 25; }); | |
print_map("条件移除后:", m); | |
cout << m.size() << endl; | |
m.clear(); | |
cout << boolalpha << "m是否为空:" << m.empty() << endl; | |
return 0; | |
} | |
/* | |
初始 map:{GPU:15}{RAM:20}{cpu:10} | |
插入不存在的:{GPU:15}{RAM:20}{SSD:30}{cpu:10} | |
移除后:{RAM:20}{SSD:30}{cpu:10} | |
条件移除后:{RAM:20}{cpu:10} | |
2 | |
m 是否为空:true | |
*/ |
# multimap
含有键值队的已排序列表,同时容纳许多个元素拥有同一键。与 map 用法相同
# 无序关联容器
在内部,元素不以任何特别顺序排序,而是组织进桶中。元素被放进哪个桶完全依赖其值的哈希,这允许对单独元素的快速访问,因为哈希一旦确定,就准确自带元素被放入的桶。
不可修改容器元素
(即使通过非 cons 迭代器), 因为修改更改元素的哈希,并破坏容器
unordered_set
: 唯一键的集合,按照键生成散列unordered_map
: 键值对的集合,按照键生成散列,键
是唯一的unordered_multiset
: 键的集合,按照键生成散列unordered_multimap
:键值队的集合,按照键生成散列
# unordered_set
含有 key 类型的唯一对象集合关联容器
# 迭代器
begin/cbegin
: 返回指向起始的迭代器end/cend
: 返回指向末尾的迭代器
# 容器
empty
:检查容器是否为空size
:返回容纳的元素数max_size
:返回可容纳的最大
元素数
# 修改器
clear
: 清除内容insert
: 插入元素或结点C++17
emplace
: 原位构造元素emplace_hint
: 使用提示原位构造元素erase
: 擦除元素swap
:交换内容extract
:从另一容器释出结点merge
: 从另一个容器接合结点
# 查找
count
:返回匹配特定键的元素数量find
:寻找带有特定键的元素contains
: 检查容器是否含有带有特定键的元素equal_range
:返回匹配特定键
的元素范围
# 桶接口
begin(size_type)/cbegin(size_type)
:返回一个迭代器,指向指定的桶的开始:返回指向下标为 n 的桶首元素的迭代器end(size_type)/cend(size_type)
: 返回一个迭代器,。返回后随下标为 n 的桶的最后元素的元素的迭代器,此元素表现为占位符,试图访问它会导致未定义行为bucket_count
: 返回容器中的桶数max_bucket_count
: 返回容器由于系统或库实现限制的能保有最大桶数bucket_size
:返回在特定的桶中的元素数量bucket
: 返回带有特定键的容,key: 要检验的关键值
# 哈希策略
load_factor
:返回每个容的平均元素数量max_load_factor
:管理每个容的平均数量的最大值rehash
:为至少为指定数量的桶预留存储空间并重新生成散列表reserve
: 为至少为指定数量的元素预留存储空间并重新生成哈希表
# 观察器
hash_function
: 返回用于对键散列的函数key_eq
: 返回用于比较键的相等性的函数
# unordered_multiset
含有可能非唯一 key 类型对象的集合
# unordered_map
含有唯一键 - 值 pair
# 迭代器
begin/cbegin
: 返回指向起始的迭代器end/cend
: 返回指向末尾的迭代器
# 容器
empty
:检查容器是否为空size
:返回容纳的元素数max_size
:返回可容纳的最大元素数
# 修改器
clear
: 清除内容insert
: 插入元素或结点C++17
emplace
: 原位构造元素emplace_hint
: 使用提示原位构造元素erase
: 擦除元素swap
:交换内容extract
:从另一容器释出结点merge
: 从另一个容器接合结点
# 查找
at
:访问指定的元素,同时进行越界
检查operator[]
: 访问或插入指定的元素count
:返回匹配特定键的元素数量find
:寻找带有特定键的元素contains``C++20
: 检查容器是否含有带有特定键的元素equal_range
:返回匹配特定键的元素范围
# 桶接口
begin(size_type)/cbegin(size_type)
:返回一个迭代器,指向指定的桶的开始:返回指向下标为 n 的桶首元素的迭代器end(size_type)/cend(size_type)
: 返回一个迭代器,。返回后随下标为 n 的桶的最后元素的元素的迭代器,此元素表现为占位符,试图访问它会导致未定义行为bucket_count
: 返回容器中的桶数max_bucket_count
: 返回容器由于系统或库实现限制的能保有最大桶数bucket_size
:返回在特定的桶中的元素数量bucket
: 返回带有特定键的容,key: 要检验的关键值
# 哈希策略
load_factor
:返回每个容的平均元素数量max_load_factor
:管理每个容的平均数量的最大值rehash
:为至少为指定数量的桶预留存储空间并重新生成散列表reserve
: 为至少为指定数量的元素预留存储空间并重新生成哈希表
# 观察器
hash_function
: 返回用于对键散列
的函数key_eq
: 返回用于比较键的相等性的函数
# unordered_multimap
支持等价的键 (一个 unordered_multimap 可含有每个键值的多个副本) 和将键与另一个类型的值关联
# 迭代器
begin/cbegin
: 返回指向起始的迭代器end/cend
: 返回指向末尾的迭代器
# 容器
empty
:检查容器是否为空size
:返回容纳的元素数max_size
:返回可容纳的最大元素数
# 修改器
clear
: 清除内容insert
: 插入元素或结点C++17
emplace
: 原位构造元素emplace_hint
: 使用提示原位构造元素erase
: 擦除元素swap
:交换内容extract
:从另一容器释出结点merge
: 从另一个容器接合结点
# 查找
count
:返回匹配特定键的元素数量find
:寻找带有特定键的元素contains``C++20
: 检查容器是否含有带有特定键的元素equal_range
:返回匹配特定键的元素范围
# 桶接口
begin(size_type)/cbegin(size_type)
:返回一个迭代器,指向指定的桶的开始:返回指向下标为 n 的桶首元素的迭代器end(size_type)/cend(size_type)
: 返回一个迭代器,。返回后随下标为 n 的桶的最后元素的元素的迭代器,此元素表现为占位符,试图访问它会导致未定义行为bucket_count
: 返回容器中的桶数max_bucket_count
: 返回容器由于系统或库实现限制的能保有最大桶数
bucket_size
:返回在特定的桶中的元素数量bucket
: 返回带有特定键的容,key
: 要检验
的关
键值
# 哈希策略
load_factor
:返回每个容的平均元素数量max_load_factor
:管理每个容的平均数量的最大值rehash
:为至少为指定数量的桶预留存储空间并重新生成散列表reserve
: 为至少为指定数量的元素预留存储空间并重新生成哈希表
# 观察器
hash_function
: 返回用于对键散列的函数key_eq
: 返回用于比较键的相等性的函数