文章

STL函数笔记

前言

本文对C++ STL标准模板库中的常用容器、算法等作一个总结,同时记录一些学习的要点,便于以后快速查阅

容器

  • 序列式容器:以线性排列存储某一类型的元素,元素都可序,但未必有序,不会自动按照值大小排序
  • 关联式容器:容器中的元素结构为<K, V>键值对,通过键可访问到值,会进行自动按升序(或比较器)排序,一般结构为树或哈希表

vector

vector,动态数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include<vector>

// 构造
vector<int> v; // 一个空的vector对象
vector<int> v(v1); // 复制v得到新的vector对象
vector<int> v(n); // 一个有n个元素的vector对象
vector<int> v(n, value); // 一个有n个value值的vector对象
vector<int> v(first, end); // 将first和end迭代器定义的序列复制到vector中

// 基本操作
v.front(); // 返回首元素
v.back(); // 返回尾元素
v.data(); // 返回指向首元素的指针
v.at(n); // 返回v[n],有边界检查
v.push_back(value); // 向表尾插入value值
v.size(); // 返回表长
v.empty(); // 判断表是否为空
v.pop_back(); // 删除表尾元素
v.begin(); // 返回指向首元素的随机存取迭代器
v.end(); // 返回指向表尾下一个位置的随机存取迭代器

// 函数
v.insert(iterator, value); // 向Iterator指向的位置前插入value
v.insert(iterator, n, value); // 向Iterator指向的位置前插入n个value
v.insert(iterator, first, last); // 向Iterator指向的位置前插入first-last序列

v.erase(iterator); // 将Iterator指向的元素删除
v.erase(first, last); // 删除first和last迭代器指定的序列

v.reserve(n); // 预分配处存储n个元素的空间
v.resize(n); // 改变表长为n,超出表长则删除,扩大则用默认值填满
v.resize(n, value); // 改变表长为n,超出表长则删除,扩大则用value填满

v.clear(); // 删除表中元素
v.swap(v1); // v与v1交换
v.assign(first, last); // 将v替换为first-last序列
operator=; // 对vector对象赋值
// 比较运算符重载按字典序比较值

string

字符串,一个字符的序列型容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include<string>

// 构造
string s; // 一个空字符串
string s("ABC"); // 一个"ABC"字符串
string s("ABC", n, length); // 从ABC上下标n处截取length长度的字符串
string s("ABC", length); // 在ABC上从0开始截取length长度的字符串
string s(str1); // 复制str1的字符串
string s(str1, n); // 从str1[n]处开始截取的字符串
string s(str1, n, length); // 从str1[n]处截取length长度的字符串
string s(length, ch); // length长度由ch组成的字符串

// 基本操作
s.front(); // 返回首字符
s.back(); // 返回尾字符
s.data(); // 返回指向首字符的指针
s.at(n); // 返回s[n]的字符,有边界检查
s.begin(); // 返回首字符的迭代器
s.end(); // 返回尾字符下一位的迭代器
s.empty(); // 判断字符串是否为空
s.size(); // 返回字符串长度
s.capacity(); // 返回分配的对象能存储的字符数量
s.push_back(ch); // 在字符串尾插入字符
s.pop_back(); // 删除字符串尾的字符
s.assign(str); // s赋值为str

// 函数
s.insert(iterator, length, ch); // 在Iterator之前插入length长度的字符ch
s.insert(n, str); // 在s[n]之前插入str
s.insert(n, str, length); // 在s[n]之前的length长度插入str,长度大于str则用空格填充
s.insert(n, length, ch); // 在s[n]之前插入length长度的字符ch

s.erase(n); // 删除从s[n]开始的字符串
s.erase(n, length); // 删除s[n]开始length长度的字符串
s.erase(iterator); // 删除Iterator指向的字符
s.erase(first, last); // 删除first-last字符序列

s.append(length, ch); // 后附length长度的字符ch
s.append(str); // 后附字符串str
s.append(str, n, length); // 后附str[n, n + length)

s.compare(str); // 比较s和str
s.compare(n, length, str); // 比较s的子串[n, n + length)和str
s.compare(n1, length1, str, n2, length2); // 比较s[n1, n1+length1)和str[n2, n2+length)

s.starts_with(str); // 判断前缀是否是str
s.starts_with(ch); // 判断前缀是否是ch
s.ends_with(str); // 判断后缀是否是str
s.ends_with(ch); // 判断后缀是否是ch

s.clear(); // 清空字符串
s.replace(n, length, str); // 将s[n, n + length)替换为str
s.substr(n, length); // 返回s[n, n + length)
s.copy(dest, length, n); // 复制s[n, n + length)到dest
s.resize(n); // 改变字符串长度为n
s.resize(n, ch); // 改变字符串长度为n并用ch填充
s.swap(str); // 交换两个字符串

s.find(str); // 查找s中的str子串
s.find(str, n, length); // 在s[n, n + length)中查找str子串
s.find(ch); // 查找首个ch字符

s.rfind(str); // 查找s中最后一个str子串
s.rfind(str, n, length); // 查找s[n, n + length)中最后一个str子串
s.rfind(ch); // 查找最后一个ch字符

stoi(str, n, base); // 从str[n]处开始按base进制转换为十进制int值
stol(str, n, base); // 从str[n]处开始按base进制转换为十进制long值
stoll(str, n, base); // 从str[n]处开始按base进制转换为十进制long long值
stof(str, n, base); // 从str[n]处开始按base进制转换为十进制float值
stod(str, n, base); // 从str[n]处开始按base进制转换为十进制double值
stold(str, n, base); // 从str[n]处开始按base进制转换为十进制long double值
to_string(value); // 将value转换为字符串

operator+=; // 后附字符或字符串
operator+; // 字符或字符串拼接
// 比较运算符重载按字典序比较字符串

stack

栈,先进后出,不支持迭代器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include<stack>

// 构造
// 第一个模板参数为元素类型
// 第二个模板参数为底层容器类型,必须满足顺序容器(vector, deque, list),默认为deque
stack<int> s; // 一个空的int栈,底层为deque
stack<int, vector<int>> s; // 一个空的int栈,底层为int型vector
stack<int, vector<int>> s(v); // 使用vector对象创建栈
stack<int> s(s1); // 将s1复制创建栈

// 基本操作
s.top(); // 访问栈顶元素
s.empty(); // 判断栈是否为空
s.size(); // 返回栈的元素数
s.push(value); // 将value插入到栈中
s.pop(); // 弹出栈顶元素,不返回
s.swap(s1); // 交换s和s1
// 比较运算符重载按字典序比较stack中的值

queue

队列,先进先出,不支持迭代器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<queue>

// 构造
// 第一个模板参数为元素类型
// 第二个模板参数为底层容器类型,必须满足顺序容器(deque, list),默认为deque
queue<int> q; // 一个空的int队列,底层为deque
queue<int, vector<int>> q; // 一个空的int队列,底层为int型vector
queue<int, vector<int>> q(first, last); // 使用first-last序列创建队列
queue<int> q(q1); // 将q1复制创建队列

// 基本操作
q.front(); // 访问队首元素
q.back(); // 访问队尾元素
q.empty(); // 判断队列是否为空
q.size(); // 返回队长
q.push(value); // 向队尾插入value
q.pop(); // 弹出队首元素,不返回
q.swap(q1); // 交换q和q1
// 比较运算符重载按字典序比较值

deque

双端队列,支持下标随机访问,可以在两端以常数时间插入和删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<deque>

// 构造
deque<int> dq; // 一个空的deque
deque<int> dq(n); // 一个有n个元素空间的deque
deque<int> dq(n, value); // 一个有n个value的deque
deque<int> dq(dq1); // 将dq1复制创建dq

// 基本操作
dq.at(n); // 返回dq[n]
dq.front(); // 返回队首元素
dq.back(); // 返回队尾元素
dq.size(); // 返回队列长度
dq.empty(); // 判断dq是否为空
dq.begin(); // 返回首元素的迭代器
dq.end(); // 返回队尾下一位的迭代器
dq.push_back(value); // 将value插入到队尾
dq.pop_back(); // 弹出队尾元素,不返回
dq.push_front(value); // 将value插入到队首
dq.pop_front(); // 弹出队首元素,不返回
dq.clear(); // 清空队列

// 函数
dq.insert(iterator, value); // 在Iterator指向位置之前插入value
dq.insert(iterator, n, value); // 在Iterator指向位置之前插入n个value

dq.erase(iterator); // 删除Iterator处的元素
dq.erase(first, end); // 删除first-end序列

dq.resize(n); // 改变容器大小为n
dq.resize(n, value); // 改变容器大小为n,多余处用value填充

dq.assign(n, value); // 将dq赋值为n个value
dq.assign(first, last); // 将dq赋值为first-last序列
// 比较运算符重载按字典序比较值

list

list通常实现为双向链表,支持以常数时间进行插入和删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include<list>

// 构造
list<int> l; // 一个空list
list<int> l(l1); // 将l1复制创建l
list<int> l(n, value); // 创建n个value的list
list<int> l(first, last); // 用first-last序列创建一个list

// 基本操作
l.front(); // 返回首元素
l.back(); // 返回尾元素
l.begin(); // 返回指向首元素的迭代器
l.end(); // 返回指向尾元素下一位的迭代器
l.size(); // 返回表长
l.empty(); // 判断表是否为空
l.clear(); // 清空表
l.push_back(value); // 在表尾插入value
l.pop_back(); // 弹出表尾元素
l.push_front(value); // 在表头插入value
l.pop_front(); // 弹出表头元素

// 函数
l.insert(iterator, value); // 在Iterator处插入value
l.insert(iterator, n, value); // 在Iterator处插入n个value

l.erase(iterator); // 删除Iterator处的元素
l.erase(first, last); // 删除first-last序列

l.resize(n); // 改变表的大小为n
l.resize(n, value); // 改变表的大小为n,多余处用value填充

l.merge(l1); // 将两个排序链表按升序合并
l.merge(l1, comparator); // 将两个排序链表按comparator比较函数排序

l.sort(); // 将表按升序排序
l.sort(comparator); // 将表按comparator比较函数排序

l.swap(l1); // 交换l和l1
l.splice(iterator, l1); // 将l中Iterator处的元素转移给l1
l.remove(value); // 删除表中的value值
l.reverse(); // 将l反转
l.unique(); // 删除表中连续的重复元素,保留第一个
// 比较运算符重载按字典序比较值

set/multiset

set自动对元素进行排序,键值对K与V相等,查找、插入、删除拥有O(logN)复杂度,通常实现为红黑树

  • set中元素唯一,不允许重复,若插入重复则不会插入
  • multiset元素可重复
  • 元素类型是自定义类型,则需要仿函数指定排序规则,在创建时传入
  • unordered_set底层使用哈希表实现,插入/删除为O(1)复杂度
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<set>
#include<multiset>

// 构造
set<int> s; // 一个空的set
set<int> s(s1); // 将s1复制创建s
set<int> s(first, last); // 用first-last序列创建set
set<int, comparator> s; // 按给定比较器创建set

// 基本操作
s.begin(); // 返回首元素迭代器
s.end(); // 返回尾元素下一位迭代器
s.empty(); // 判断set是否为空
s.size(); // 返回set元素数
s.clear(); // 清空set
s.swap(s1); // 交换s和s1
s.find(key); // 返回键为key的元素的迭代器
s.contains(key); // 判断set中是否有键为key的元素
s.count(key); // 返回键为key的元素数量

// 函数
s.insert(value); // 插入value
s.insert(first, last); // 插入first-last序列

s.erase(iterator); // 删除Iterator处的元素
s.erase(first, last); // 删除first-last序列
s.erase(key); // 删除键为key的元素

s.equal_range(key); // 返回键为key的元素的范围(迭代器对)
s.lower_bound(key); // 返回首个键不小于key的元素的迭代器
s.upper_bound(key); // 返回首个键大于key的元素的迭代器
s.key_comp(); // 返回用于比较键的函数
s.value_comp(); // 返回用于比较值的函数
s.merge(s1); // 将s和s1合并
// 比较运算符重载按字典序比较值

pair

pair,表示一对数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<iostream>

// 构造
pair<int, int> p; // 一个空对
pair<int, int> p(value1, value2); // 一个value1和value2的数据对
pair<int, int> p(p1); // 用p1创建p

// 基本操作
p.first; // 数对的首元素
p.second; // 数对的第二个元素

// 函数
make_pair(value1, value2); // 创建value1和value2的数对
// 比较运算符重载按字典序比较

map/multimap

map中存储键值对<K, V>并自动进行排序,查找、插入、删除拥有O(logN)复杂度,通常实现为红黑树

  • map键值唯一,multimap键值不唯一
  • 元素类型是自定义类型,需要仿函数指定排序规则
  • unordered_map底层使用哈希表实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<map>
#include<multimap>

// 构造
map<int, int> m; // 一个空的map
map<int, int> m(first, last); // 用first-last序列创建map
map<int, int> m(m1); // m1复制创建m
map<int, int, comparator> m; // 用给定比较器创建map

// 基本操作
m.at(key); // 访问键为key的值
operator[]; // 下标访问键为key的值
m.begin(); // 返回首元素的迭代器
m.end(); // 返回尾元素的迭代器
m.empty(); // 判断map是否为空
m.size(); // 返回map中的元素数
m.clear(); // 清空map
m.count(key); // 返回键为key的元素数量
m.swap(m1); // 将m和m1交换
m.find(key); // 返回键为key的元素的迭代器
m.contains(key); // 判断map中是否包含键为key的元素

// 函数
m.insert(pair); // 插入pair
m.insert(first, last); // 插入first-last序列

m.erase(iterator); // 删除Iterator处的元素
m.erase(first, last); // 删除first-last序列

m.equal_range(key); // 返回键为key的元素范围的迭代器对
m.lower_bound(key); // 返回首个键不小于key的元素的迭代器
m.upper_bound(key); // 返回首个键大于key的元素的迭代器
m.key_comp(); // 返回用于比较键的函数
m.value_comp(); // 返回用于比较值的函数
m.merge(m1); // 将m与m1合并

算法

STL库中提供的工具函数,基于容器的迭代器进行操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#include<algorithm>

// 不修改序列的操作
all_of(first, last, predicate); // 判断predicate对[first-last]每个元素是否都为true
any_of(first, last, predicate); // 判断predicate对[first-last]每个元素是否至少有一个为true
none_of(first, last, perdicate); // 判断predicate对[first-last]每个元素是否都不为true

for_each(first, last, function); // 对first-last序列每个元素应用function
for_each_n(first, n, function); // 对first开始的前n个元素应用function

count(first, last, value); // 返回first-last序列中等于value的元素数
count_if(first, last, predicate); // 返回predicate对first-last序列中返回true的元素数

mismatch(first1, last1, first2); 
// 返回[first1, last1)和[first2, last)的首个不匹配项的迭代器对
mismatch(first1, last1, first2, last2);
// 返回[first1, last1)和[first2, last2)的首个不匹配项的迭代器对
mismatch(first1, last1, first2, predicate);
// 返回[first1, last1)和[first2, last)的首个predicate为false项的迭代器对
mismatch(first1, last1, first2, last2, predicate);
// 返回[first1, last1)和[first2, last2)的首个predicate为false项的迭代器对

find(first, last, value); // 返回[first, last)中首个等于value项的迭代器
find_if(first, last, predicate); // 返回[first, last)中首个predicate为true项的迭代器
find_if_not(first, last, predicate); // 返回[first, last)首个predicate为false项的迭代器

find_end(first1, last1, first2, last2);
// 返回[first1, last1)中[first2, last2)最后一次匹配处的迭代器
find_end(first1, last1, first2, last2, predicate);
// 返回[first1, last1)中[first2, last2)最后一次predicate对每个元素为true处的迭代器
find_first_of(first1, last1, first2, last2);
// 返回[first1, last1)中首个与[first2, last2)元素相等的元素的迭代器
find_first_of(first1, last1, first2, last2, predicate);
// 返回[first1, last1)中首个与[first2, last2)元素predicate为true的元素的迭代器
adjacent_find(first, last);
// 返回[first, last)中首个相邻的重复元素的迭代器
adjacent_find(first, last, predicate);
// 返回[first, last)中首个相邻的predicate为true的元素的迭代器
search(first1, last1, first2, last2);
// 返回[first1, last1)中子序列[first2, last2)首次出现处的迭代器
search(first1, last1, first2, last2, predicate);
// 返回[first1, last1)中子序列[first2, last2)首次predicate为true处的迭代器
search_n(first, last, n, value);
// 返回[first, last)中n个等于value的序列的迭代器
search_n(first, last, n, value, prediacate);
// 返回[first, last)中n个predicate对元素与value为true的序列的迭代器

// 修改序列的操作
copy(first1, last1, first2);
// 复制[first1, last1)到开始于first2的另一范围
copy_if(first1, last1, first2, predicate);
// 复制[first1, last1)中predicate为true的元素到开始于first2的另一范围
copy_n(first1, n, first2);
// 复制开始于first1的n个元素到开始于first2的另一范围
copy_backward(first1, last1, last2);
// 复制[first1, last1)到终于last2的另一范围(从后往前复制)

fill(first, last, value); // 将value赋值给[first, last)
fill_n(first, n, value); // 将开始于first的n个元素赋值为value

transform(first1, last1, first2, unaryFunction);
// 将一元函数unaryFunction应用到[first1, last1)并存储结果到开始于first2的范围
transform(first1, last1, first2, output, binaryFunction);
// 将二元函数应用到[first1, last1)和开始于first2的范围并存储结果到开始于output的范围

generate(first, last, function);
// 将function生成的值赋值给[first, last)
generate_n(first, n, function);
// 将function生成的值赋值给开始于first的n个元素

remove(first, last, value);
// 移除[first, last)中等于value的元素
remove_if(first, last, predicate);
// 移除[first, last)中predicate为true的元素
remove_copy(first1, last1, first2, value);
// 复制[first1, last1)到开始于first2的范围,忽略等于value的元素
remove_copy_if(first1, last1, first2, predicate);
// 复制[first1, last1)到开始于first2的范围,忽略predicate为true的元素

replace(first, last, oldValue, newValue);
// 替换[first, last)所有等于oldValue的元素
replace_if(first, last, predicate, newValue);
// 替换[first, last)所有predicate为true的元素
replace_copy(first1, last1, first2, oldValue, newValue);
// 复制[first1, last1)到开始于first2的范围并替换原序列等于oldValue的元素
replace_copy_if(first1, last1, first2, predicate newValue);
// 复制[first1, last1)到开始于first2的范围并替换原序列中predicate为true的元素

swap(x, y); // 交换x和y
swap_ranges(first1, last1, first2); // 交换[first1, last1)和开始于first2的范围
iter_swap(first, second); // 交换first和second指向的元素

reverse(first, last);
// 反转[first, last)
reverse_copy(first1, last1, first2);
// 复制[first1, last1)到开始于first2的范围并将新序列逆序

rotate(first1, first2, last1);
// 对[first1, last1)进行左旋转,满足旋转后first2处成为新范围的首元素
rotate_copy(first1, first2, last1, output);
// 将[first1, last1)复制到开始于output的范围并左旋转,满足first2处成为新范围的首元素

unique(first, last);
// 删除[first, last)中的连续重复元素,保留第一个
unique(first, last, predicate);
// 删除[first, last)中连续predicate为true的元素,保留第一个
unique_copy(first1, last1, first2);
// 复制[first1, last1)到开始于first2的范围并删除连续重复元素,保留第一个
unique_copy(first1, last1, first2, predicate);
// 复制[first1, last1)到开始于first2的范围并删除连续predicate为true的元素,保留第一个

next_permutation(first, last);
// 修改first-last序列为字典序中当前序列的下一个序列
prev_permutation(first, last);
// 修改first-last序列为字典序中当前序列的上一个序列

// 划分操作
is_partitioned(first, last, predicate);
// 判断[first, last)中predicate为true的元素是否都在predicate为false元素之前
partition(first, last, predicate);
// 将[first, last)中predicate为true的元素排在predicate为false的元素之前
partition_copy(first1, last1, first2, first3, predicate);
// 将[first1, last1)中predicate为true的元素复制到first2范围,为false的元素复制到first3范围
stable_partition(first, last, predicate);
// 将[first, last)中predicate为true的元素排在predicate为false的元素之前,保持相对顺序
partition_point(first, last, predicate);
// 定位划分范围[first, last)中首个predicate为false的元素

// 排序操作
is_sorted(first, last); // 判断序列是否为升序
is_sorted(first, last, comparator); // 判断序列是否符合比较器排序
is_sorted_until(first, last); // 查找序列中的最大已排序子序列
is_sorted_until(first, last, comparator); // 查找序列中最大符合比较器排序的子序列

sort(first, last); // 将序列按升序排序
sort(first, last, comparator); // 将序列按比较器顺序排序
stable_sort(first, last); // 稳定排序
stable_sort(first, last, comparator); // 按比较器顺序稳定排序

partial_sort(first, middle, last);
// 将[first, last)中已排序的最小元素重排到[first, middle)
partial_sort(first, middle, last, comparator);
// 将[first, last)中按比较器排序的最小元素重排到[first, middle)
partial_sort_copy(first1, last1, first2, last2);
// 将[first1, last1)排序结果存储到[first2, last2),不改变原序列

// 二分查找操作(已升序排序范围)
lower_bound(first, last, value);
// 返回序列中首个大于或等于value的元素的迭代器
upper_bound(first, last, value);
// 返回序列中首个大于value的元素的迭代器
binary_search(first, last, value);
// 在序列中二分查找value
merge(first1, last1, first2, last2, output);
// 将[first1, last1)和[first2, last2)合并存储到output范围

// 集合操作(已排序范围)
includes(first1, last1, first2, last2);
// 判断[first1, last1)是否是[first2, last2)的子序列
set_difference(first1, last1, first2, last2, output);
// 取两个已排序序列的差集并复制到开始于output的范围
set_intersection(first1, last1, first2, last2, output);
// 取两个已排序序列的交集并复制到开始于output的范围
set_union(first1, last1, first2, last2, output);
// 取两个已排序序列的并集并复制到开始于output的范围

// 最大/最小操作
max(x, y); // 返回x, y的较大者
max_element(first, last); // 返回序列中最大元素
min(x, y); // 返回x, y的较小者
min_element(first, last); // 返回序列中的最小元素
minmax_element(first, last); // 返回序列中的最大和最小元素
_gcd(x, y); // 返回x, y的最大公因子
accumulate(first, last, val); // 将first-last序列求和,val为初值,返回值与val类型相同

// 比较操作
equal(first1, last1, first2);
// 判断两个序列是否相等
equal(first1, last1, first2, last2);
// 判断两个序列是否相等
equal(first1, last1, first2, predicate);
// 判断两个序列predicate是否为true
equal(first1, last1, first2, last2, predicate);
// 判断两个序列predicate是否为true
lexicographical_compare(first1, last1, first2, last2);
// 判断[first1, last1)是否按字典序小于[first2, last2)

迭代器

迭代器是容器与算法之间的中介,迭代器可以看做指针,支持类似指针的操作

迭代器操作

通用迭代器操作

  • *it:访问当前迭代器指向的元素
  • it1 == it2:判断迭代器相等
  • it1 != it2:判断迭代器不相等

不同类型的迭代器支持不同的操作

  • 前向迭代器:前向访问,支持自增操作
  • 双向迭代器:双向访问,支持自增自减操作
  • 随机迭代器:随机访问,支持迭代器移动任意单位访问
  • 输入迭代器:只支持前向访问读取
  • 输出迭代器:只支持前向访问写入

迭代器获取

通常通过容器提供的以下函数来获取迭代器

  • begin()/end():迭代器类型T::iterator,前向访问,可读写
  • cbegin()/end():迭代器类型T::const_iterator,前向访问,可读不可写
  • rbegin()/rend():迭代器类型T::reverse_interator,反向访问,可读写
  • crbegin()/crend():迭代器类型T::const_reverse_interator,反向访问,可读不可写
  • begin(T)/end(T):C++11工具方法,支持数组的迭代器访问

迭代器失效

以下两种情况会导致迭代器失效

  • 对于序列型容器,修改元素不会导致迭代器失效,插入或删除可能导致迭代器失效
  • 对于关联型容器,修改、插入、删除都可能导致迭代器失效

仿函数

  • 仿函数又称为函数对象,是一个实行函数功能的类,该类必须重载函数调用运算符(operator())

  • 函数对象可以有自己的状态,如记录函数调用次数,是否允许调用
  • 可以作为参数传递
1
2
3
4
5
6
class MyComparator {
public:
    bool operator()(int x, int y) const {
        return x > y;
    }
};

谓词:返回bool型的仿函数称为谓词。参数列表含有一个参数,称为一元谓词,含有两个参数,称为二元谓词

内建仿函数

STL中提供的一些仿函数,主要用于条件判断和基本运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<functional>

// 算术仿函数
template<class T> plus<T>; // x + y
template<class T> minus<T>; // x - y
template<class T> multiplies<T>; // x * y
template<class T> divides<T>; // x / y
template<class T> modulus<T>; // x % y
template<class T> negate<T>; // -x

// 比较仿函数
template<class T> equal_to<T>; // x == y
template<class T> not_equal_to<T>; // x != y
template<class T> greater<T>; // x > y
template<class T> less<T>; // x < y
template<class T> greater_equal<T>; // x >= y
template<class T> less_equal<T>; // x <= y

// 逻辑仿函数
template<class T> logical_and<T>; // x && y
template<class T> logical_or<T>; // x || y
template<class T> logical_not<T>; // !x
本文由作者按照 CC BY 4.0 进行授权