$STL$ 容器
$vector$ 变长数组
包含在 < vector > 头文件中
基本思想:倍增
系统为某一程序分配空间时,所用时间与空间大小无关,只与申请次数有关。因此 vector
为保证效率,需要尽可能减少申请次数。**vector
使用倍增的思想分配空间**
vector
在定义时,先开辟一定长度的空间,当元素个数大于当前数组长度时,开一个两倍于该长度的空间,再将原数组复制进新数组
由此可知,当开辟一个长度为 n
的 vector
数组时,需进行 log2n 次开辟空间的操作,总复制次数为 n
,平均插入每个数的时间复杂度是 O(1)
定义
1 | vector<int> a; |
操作函数
O(1):
1 | a.size(); |
O(n);
1 | a.clear(); |
迭代器:
1 | a.begin(); |
- vector 还支持随机寻址。即可以使用
a[2]
访问 a 数组第 3 个元素
遍历 vector 数组
1 | for (int i = 0; i < a.size(); i ++) |
- vector 还支持按照字典序比较两数组,直接使用运算符比较即可
$pair$ 二元组
定义:
1 | pair<int, string> a; |
操作函数
1 | a.first(); |
- 支持比较远算,与 vector 一样是按照字典序排序,以 first 为第一关键字,以 second 为第二关键字
ps: 一些奇技淫巧
如果有三个关键字需存储,我们仅需:
1 | pair<int, pair<int, int>> a; |
即在 p 中存入了三个整型变量
$string$ 字符串
定义
1 | string a; |
操作函数
1 | a.size(); || a.length(); |
- 字符串可以支持
+
运算,使用a + b
即可将 a 和 b 两个字符串首位拼接在一起
$queue$ 队列
包含在 < queue > 头文件中
定义
1 | queue<int> q; |
操作函数
1 | a.size(); |
$deque$ 双端队列
常数和空间都极大,不建议使用
操作函数
$O(1)$
1 | a.size(); |
迭代器:
1 | a.begin(); |
- deque 还支持随机寻址。即可以使用
a[2]
访问队列 a 从左往右数第 3 个元素
$priority_queue$ 优先队列 / 堆
具体的实现方式,可见[[2022.11.12 - 堆]]
定义
1 | priority_queue<int> heap; |
操作函数
1 | heap.push(); |
$stack$ 栈
定义
1 | stack<int> heap; |
操作函数
1 | heap.push(); |
$set$ & $multiset$ 有序集合 & 有序多重集合
基于平衡二叉树(红黑树)实现
可动态维护有序序列,因此不支持随机寻址set 中不会出现重复元素,重复插入的元素会被忽略。
multiset 允许重复元素的存在。
操作函数
$O(1)$
1 | a.size(); |
$O(log_2n)$
1 | a.insert(x); |
$map$ & $multimap$ 映射
包含在 < map > 头文件中
- 基于平衡二叉树 (红黑树) 实现
动态维护有序序列
定义
1 | map<string, int> a; |
操作函数
$O(1)$
1 | a.size(); |
$O(log_2n)$
1 | a.insert(); |
访问与遍历
使用 a[x]
访问时,如果无法找到,则新建一个 $key$ 为 $x$ 的 $map$,$val$ 指向 $0$
1 | for (auto x : a) |
注意:在遍历中无法修改 $key$,只能修改 $value$
特殊使用
1 | cout << a["wangk"] << endl; |
输出 1
,时间复杂度为 $O(log_2n)$
$unordered_set$ & $unordered_map$ 无序集合 / 映射
$unordered_multiset$ & $unordered_multimap$ 多重无序集合 / 映射
总体操作和 set
map
等类似,操作的时间复杂度为 O(1),不支持 lower_bound()
和upper_bound()
以及 map
的特殊使用方法
注意:在初始化时会开 4 倍空间,警钟敲烂
bitset 压位
定义
1 | bitset<10000> s; |
操作
~
&
|
^
>>
<<
==
!=
- 取某一位
s[]
1 | s.count(); |
STL 函数
需引入 <alrorithm>
头文件
- 规定下文中
begin
和end
均为迭代器
1 | min(x, y); |
值得注意的是,random_shuffle
自 C++14 起被弃用,C++17 起被移除。我们可以使用 shuffle
函数代替原来的 random_shuffle
。使用方法为:
1 | shuffle(v.begin(), v.end(), rng); |
(最后一个参数传入的是使用的随机数生成器,一般情况使用以真随机数生成器 random_device 播种的梅森旋转伪随机数生成器 mt19937)。