目录
1. 顺序容器
顺序容器在内存中以线性方式存储元素,可以方便地进行顺序访问。常用的顺序容器有:
1.1 std::vector
动态数组,可以在末尾高效地插入和删除元素
-
构造函数:
vector<T> v;
默认构造空向量。vector<T> v(n);
创建含n
个元素的向量,每个元素初始化为T()
。vector<T> v(n, value);
创建含n
个元素的向量,每个元素初始化为value
。vector<T> v{1, 2, 3};
列表初始化向量。
-
常用成员函数:
v.size();
返回元素个数。v.push_back(value);
在末尾添加元素。v.pop_back();
删除末尾元素。v[i];
随机访问第i
个元素。v.begin();
返回指向第一个元素的迭代器。v.end();
返回指向最后一个元素之后位置的迭代器。v.empty();
检查向量是否为空。v.clear();
清空向量中的所有元素。
for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " "; // 解引用迭代器访问元素
}
1.2 std::deque
(双端队列)
支持在头部和尾部进行高效的插入和删除操作,同时可以随机访问元素。
-
构造函数:
deque<T> d;
默认构造空双端队列。deque<T> d(n);
创建含n
个元素的双端队列,每个元素初始化为T()
。deque<T> d{1, 2, 3};
列表初始化双端队列。
-
常用成员函数:
d.push_back(value);
在末尾添加元素。d.push_front(value);
在前端添加元素。d.pop_back();
删除末尾元素。d.pop_front();
删除前端元素。d[i];
随机访问第i
个元素。d.front();
访问第一个元素。d.back();
访问最后一个元素。
1.3 std::list
(双向链表)
双向链表,可以在任意位置高效插入和删除元素,但不支持随机访问。
-
构造函数:
list<T> l;
默认构造空链表。list<T> l(n);
创建含n
个元素的链表,每个元素初始化为T()
。list<T> l{1, 2, 3};
列表初始化链表。
-
常用成员函数:
l.push_back(value);
在末尾添加元素。l.push_front(value);
在前端添加元素。l.pop_back();
删除末尾元素。l.pop_front();
删除前端元素。l.insert(it, value);
在迭代器it
所指位置前插入元素。l.erase(it);
删除迭代器it
所指向的元素。l.begin();
返回指向第一个元素的迭代器。l.end();
返回指向最后一个元素之后位置的迭代器。
for (std::list<int>::iterator it = lst.begin(); it != lst.end(); ++it) {
std::cout << *it << " "; // 解引用迭代器访问元素
}
1.4 std::forward_list
(单向链表)
单向链表,只有向前的链接,内存使用更少,但功能不如 std::list
。
构造函数:
std::forward_list<T> fl;
默认构造一个空链表。std::forward_list<T> fl(n);
创建含n
个元素的链表,每个元素初始化为T()
。std::forward_list<T> fl{1, 2, 3};
列表初始化链表。
常用成员函数:
fl.push_front(value);
在前端添加元素。fl.pop_front();
删除前端元素。fl.insert_after(it, value);
在迭代器it
所指位置之后插入元素。fl.erase_after(it);
删除迭代器it
所指向的下一个元素。fl.begin();
返回指向第一个元素的迭代器。fl.end();
返回指向最后一个元素之后位置的迭代器。
1.5 std::array
定长数组,大小在编译时固定,提供类似于 C 风格数组的功能,但具有更多的 STL 接口。
构造函数:
std::array<T, N> arr;
默认构造一个大小为N
的数组,元素类型为T
。std::array<T, N> arr = {1, 2, 3};
列表初始化数组。std::array<int, 3> arr = {};
使用值初始化,所有元素均为0
。
常用成员函数
arr.size();
返回数组的大小(固定为N
)。arr.empty();
检查数组是否为空(对于std::array
,它总是返回false
,因为数组的大小固定)。arr.front();
返回数组的第一个元素的引用。arr.back();
返回数组的最后一个元素的引用。arr.data();
返回指向数组的底层原始指针(与 C 风格数组兼容)。arr.fill(value);
用value
填充整个数组。arr[i];
:使用下标访问元素。
11.6 std::string
专门用于存储和操作字符的顺序容器,实际上是一个 std::basic_string<char>
的实例。
构造与初始化:
std::string s;
默认构造一个空字符串。std::string s("Hello");
从 C 风格字符串构造。std::string s(10, 'A');
构造一个包含 10 个字符 'A' 的字符串。std::string s = "Hello";
使用字符串字面量初始化。
常用成员函数:
-
大小与容量
s.size();
或s.length();
返回字符串的长度(字符个数)。s.empty();
检查字符串是否为空。s.capacity();
返回字符串在重新分配内存前的容量。s.resize(n)
;调整字符串大小为n
,如果n
大于当前大小,则添加字符。
-
访问元素:
s[i];
访问字符串的第i
个字符(下标操作符)。s.at(i);
访问第i
个字符并进行范围检查,若越界会抛出异常。s.front();
返回第一个字符的引用。s.back();
返回最后一个字符的引用。
-
字符串操作:
s.append(str);
或s += str;
将字符串str
追加到当前字符串末尾。s.insert(pos, str);
在位置pos
处插入字符串str
。s.erase(pos, len);
从位置pos
开始删除len
个字符。s.replace(pos, len, str);
用字符串str
替换从位置pos
开始的len
个字符。s.substr(pos, len);
返回从位置pos
开始长度为len
的子字符串。
-
查找与比较:
s.find(str);
查找字符串str
在当前字符串中的位置,若找不到则返回std::string::npos
。s.rfind(str);
从右向左查找str
的位置。s.compare(str);
按字典顺序比较当前字符串与str
。
-
其他操作:
s.c_str();
返回指向 C 风格字符串(以'\0'
结尾)的指针。s.data();
返回指向内部字符数组的指针(不保证以'\0'
结尾)。s.clear();
清空字符串内容。
2. 关联容器
关联容器用于快速查找、插入、删除元素,它们通常通过某种排序方式或哈希方式进行管理。常用的关联容器有:
2.1 std::set
元素按键值排序的集合,元素不重复,支持高效查找、插入和删除操作。
-
构造函数:
set<T> s;
默认构造空集合。set<T> s{1, 2, 3};
列表初始化集合。
-
常用成员函数:
s.insert(value);
插入元素,自动排序。s.erase(value);
删除元素。s.find(value);
返回指向元素的迭代器,找不到则返回s.end()
。s.begin();
返回指向第一个元素的迭代器。s.end();
返回指向最后一个元素之后位置的迭代器。
2.2 std::multiset
与 std::set
类似,但允许重复元素。
-
构造函数:
std::multiset<T> ms;
默认构造一个空的multiset
。std::multiset<T> ms = {1, 2, 3, 4};
使用列表初始化构造一个multiset
。std::multiset<T> ms(first, last);
构造一个multiset
,元素来自区间[first, last)
。
-
插入与删除
ms.insert(value);
插入元素value
。插入操作会按顺序将元素放置在适当位置。ms.erase(value);
删除multiset
中所有等于value
的元素。ms.erase(it);
删除迭代器it
所指向的元素。
-
查找与计数
ms.find(value);
返回一个迭代器,指向multiset
中第一个等于value
的元素。如果没有找到,返回ms.end()
。ms.count(value);
返回multiset
中等于value
的元素的数量。ms.lower_bound(value);
返回一个迭代器,指向第一个不小于value
的元素。ms.upper_bound(value);
返回一个迭代器,指向第一个大于value
的元素。ms.equal_range(value);
返回一对迭代器,分别指向第一个不小于value
的位置和第一个大于value
的位置。
-
遍历
ms.begin();
返回指向第一个元素的迭代器。ms.end();
返回指向最后一个元素之后位置的迭代器。ms.rbegin();
返回指向最后一个元素的反向迭代器。ms.rend();
返回指向第一个元素之前位置的反向迭代器。
-
大小与容量
ms.size();
返回multiset
中元素的数量。ms.empty();
检查multiset
是否为空。ms.max_size();
返回multiset
能够容纳的最大元素数量。
2.3 std::map
键值对(key-value)的关联容器,键唯一,按键排序,支持高效查找、插入和删除操作。
-
构造函数:
map<Key, T> m;
默认构造空映射。map<Key, T> m{{key1, value1}, {key2, value2}};
列表初始化映射。
-
常用成员函数:
m[key];
访问或插入键值对。m.insert({key, value});
插入键值对。m.erase(key);
删除指定键的键值对。m.find(key);
返回指向键的迭代器,找不到则返回m.end()
。m.begin();
返回指向第一个键值对的迭代器。m.end();
返回指向最后一个键值对之后位置的迭代器。
2.4 std::multimap
与 std::map
类似,但允许键重复。
-
构造与初始化
std::multiset<T> ms;
默认构造一个空的multiset
。std::multiset<T> ms = {1, 2, 3, 4};
使用列表初始化构造一个multiset
。std::multiset<T> ms(first, last);
构造一个multiset
,元素来自区间[first, last)
。
-
插入与删除
ms.insert(value);
插入元素value
。插入操作会按顺序将元素放置在适当位置。ms.erase(value);
删除multiset
中所有等于value
的元素。ms.erase(it);
删除迭代器it
所指向的元素。
-
查找与计数
ms.find(value);
返回一个迭代器,指向multiset
中第一个等于value
的元素。如果没有找到,返回ms.end()
。ms.count(value);
返回multiset
中等于value
的元素的数量。ms.lower_bound(value);
返回一个迭代器,指向第一个不小于value
的元素。ms.upper_bound(value);
返回一个迭代器,指向第一个大于value
的元素。ms.equal_range(value);
返回一对迭代器,分别指向第一个不小于value
的位置和第一个大于value
的位置。
-
遍历
ms.begin();
返回指向第一个元素的迭代器。ms.end();
返回指向最后一个元素之后位置的迭代器。ms.rbegin();
返回指向最后一个元素的反向迭代器。ms.rend();
返回指向第一个元素之前位置的反向迭代器。
-
大小与容量
ms.size();
返回multiset
中元素的数量。ms.empty();
检查multiset
是否为空。ms.max_size();
返回multiset
能够容纳的最大元素数量。
2.5 std::unordered_set
不保证元素的顺序;元素的存储位置是基于其哈希值计算的,元素不重复,支持常数时间的查找、插入和删除操作。
-
构造函数:
unordered_set<T> us;
默认构造空无序集合。unordered_set<T> us{1, 2, 3};
列表初始化无序集合。
-
常用成员函数:
us.insert(value);
插入元素。us.erase(value);
删除元素。us.find(value);
返回指向元素的迭代器,找不到则返回us.end()
。us.begin();
返回指向第一个元素的迭代器。us.end();
返回指向最后一个元素之后位置的迭代器。
2.6 std::unordered_multiset
与 std::unordered_set
类似,但允许重复元素。
-
构造与初始化
std::unordered_multiset<T> ums;
默认构造一个空的unordered_multiset
。std::unordered_multiset<T> ums = {1, 2, 3, 4};
使用列表初始化构造一个unordered_multiset
。std::unordered_multiset<T> ums(first, last);
构造一个unordered_multiset
,元素来自区间[first, last)
。
-
插入与删除
ums.insert(value);
插入元素value
,允许重复的元素存在。ums.erase(value);
删除unordered_multiset
中所有等于value
的元素。ums.erase(it);
删除迭代器it
所指向的元素。
-
查找与计数
ums.find(value);
返回一个迭代器,指向unordered_multiset
中第一个等于value
的元素。如果没有找到,返回ums.end()
。ums.count(value);
返回unordered_multiset
中等于value
的元素的数量。ums.equal_range(value);
返回一对迭代器,分别指向等于value
的元素的第一个位置和最后一个位置之后的位置。
-
遍历
ums.begin();
返回指向第一个元素的迭代器。ums.end();
返回指向最后一个元素之后位置的迭代器。ums.cbegin();
和ums.cend();
返回常量迭代器,用于只读访问。
-
大小与容量
ums.size();
返回unordered_multiset
中元素的数量。ums.empty();
检查unordered_multiset
是否为空。ums.max_size();
返回unordered_multiset
能够容纳的最大元素数量。
2.7 std::unordered_map
键值对(key-value)的无序关联容器,键唯一,不保证元素的顺序;元素的存储位置是基于其哈希值计算的,支持常数时间的查找、插入和删除操作。
-
构造函数:
unordered_map<Key, T> um;
默认构造空无序映射。unordered_map<Key, T> um{{key1, value1}, {key2, value2}};
列表初始化无序映射。
-
常用成员函数:
um[key];
访问或插入键值对。um.insert({key, value});
插入键值对。um.erase(key);
删除指定键的键值对。um.find(key);
返回指向键的迭代器,找不到则返回 `um
2.8 std::unordered_multimap
与 std::unordered_map
类似,但允许键重复。
-
构造与初始化
std::unordered_multimap<K, V> umm;
默认构造一个空的unordered_multimap
。std::unordered_multimap<K, V> umm = {{1, "one"}, {2, "two"}, {1, "uno"}};
使用列表初始化构造一个unordered_multimap
。std::unordered_multimap<K, V> umm(first, last);
构造一个unordered_multimap
,元素来自区间[first, last)
。
-
插入与删除
umm.insert({key, value});
插入键值对{key, value}
,允许重复的键存在。umm.erase(key);
删除unordered_multimap
中所有键等于key
的元素。umm.erase(it);
删除迭代器it
所指向的元素。umm.clear();
删除所有元素。
-
查找与计数
umm.find(key);
返回一个迭代器,指向unordered_multimap
中第一个键等于key
的元素。如果没有找到,返回umm.end()
。umm.count(key);
返回unordered_multimap
中键等于key
的元素的数量。umm.equal_range(key);
返回一对迭代器,分别指向键等于key
的元素的第一个位置和最后一个位置之后的位置。
-
遍历
umm.begin();
返回指向第一个元素的迭代器。umm.end();
返回指向最后一个元素之后位置的迭代器。umm.cbegin();
和umm.cend();
返回常量迭代器,用于只读访问。
-
大小与容量
umm.size();
返回unordered_multimap
中元素的数量。umm.empty();
检查unordered_multimap
是否为空。umm.max_size();
返回unordered_multimap
能够容纳的最大元素数量。
3. 容器适配器
容器适配器为现有容器提供了不同的接口或限制操作方式。常用的容器适配器有:
3.1 std::stack
栈适配器,通常基于 std::deque
或 std::vector
实现,只允许后进先出(LIFO)的操作。
-
构造与初始化
std::stack<T> s;
默认构造一个空的栈,使用std::deque
作为底层容器。std::stack<T, Container> s(container);
使用指定的容器container
初始化栈。
-
元素访问
s.top();
返回栈顶元素的引用。注意,栈顶元素是最后插入的元素。
-
容量
s.empty();
检查栈是否为空。如果栈为空,则返回true
。s.size();
返回栈中元素的数量。
-
修改操作
s.push(value);
将value
插入到栈顶。s.pop();
移除栈顶元素。pop
操作不会返回栈顶元素,仅将其移除。s.emplace(args...);
原地构造一个元素并将其插入到栈顶。
3.2 std::queue
队列适配器,通常基于 std::deque
实现,只允许先进先出(FIFO)的操作。
-
构造与初始化
std::queue<T> q;
默认构造一个空的队列,使用std::deque
作为底层容器。std::queue<T, Container> q(container);
使用指定的容器container
初始化队列。
-
元素访问
q.front();
返回队列前端元素的引用。前端元素是最早插入的元素。q.back();
返回队列末尾元素的引用。末尾元素是最近插入的元素。
-
容量
q.empty();
检查队列是否为空。如果队列为空,则返回true
。q.size();
返回队列中元素的数量。
-
修改操作
q.push(value);
将value
插入到队列的末尾。q.pop();
移除队列前端的元素。pop
操作不会返回前端元素,仅将其移除。
3.3 std::priority_queue
优先队列适配器,通常基于 std::vector
实现,支持按优先级排序的元素插入和访问。
-
构造与初始化
std::priority_queue<T> pq;
默认构造一个空的优先队列,使用std::vector
和最大堆作为底层容器。std::priority_queue<T, Container, Compare> pq(container, comp);
使用指定的容器container
和比较函数comp
初始化优先队列。
-
元素访问
pq.top();
返回优先队列中优先级最高的元素的引用。顶端元素是优先级最高的元素。
-
容量
pq.empty();
检查优先队列是否为空。如果优先队列为空,则返回true
。pq.size();
返回优先队列中元素的数量。
-
修改操作
pq.push(value);
将value
插入到优先队列中,元素会按优先级排序。pq.pop();
移除优先队列中优先级最高的元素。
4. STL常用算法:
算法主要是由头文件:<algorithm> <functional> <numeric> 组成
- <algorithm>:是所有STL头文件中最大的一个,范围涉及到比较、交换、查找、遍历、复制、修改等操作
- <numeric>:体积很小,只包含几个在序列上面进行简单数学运算的模板函数
- <functional>:定义了一些模板类,用以声明函数对象
4.1 常用遍历算法
4.1.1 for_each
常用的遍历算法,实现遍历容器;
函数原型:
for_each(iterator beg, iterator end, _func);
- beg:开始迭代器
- end:结束迭代器
- _func:函数或者函数对象
4.1.2 transform
遍历算法,搬运容器到另一个容器之中
函数原型:
transform(iterator beg1, iterator end1, iterator beg2, _func);
- beg1:源容器开始迭代器
- end1:源容器结束迭代器
- beg2:目标容器开始迭代器
- _func:函数或者函数对象(在搬运的过程中对迭代器中数据进行处理,不处理也可)
注意:目标容器需要提前开辟空间:使用 resize( );
vTarget.resize(v.size());
4.2 常用查找算法
4.2.1 find
查找指定元素,找到返回指定元素的迭代器,找不到返回结束迭代器 end( );
函数原型:
find(iterator beg, iterator end, value);
- 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置;
- beg:开始迭代器
- end:结束迭代器
- value:查找的元素
4.2.1 find_if
按条件查找元素
函数原型:
find_if(iterator beg, iterator end, _Pred);
- 按值查找元素,找到返回指定位置迭代器,找不到返回结束迭代器位置
- beg:开始迭代器
- end:结束迭代器
- _Pred:函数或者谓词(返回bool 类型的仿函数)
4.2.2 adjacent_find
查找相邻重复元素
函数原型:
adjacent_find(iterator beg, iterator end);
- 查找相邻重复元素,返回相邻元素的第一个位置的迭代器
- beg开始迭代器
- end结束迭代器
4..2.3 binary_search
查找指定元素是否存在,查到返回true,否则返回false,注意在无序序列中不可用
函数原型:
bool binary_search(iterator beg, iterator end, value);
- beg:开始迭代器
- end:结束迭代器
- value:查找的元素
4.2.4 conut
统计元素个数
函数原型:
count(iterator beg, iterator end, value);
- 统计元素出现的次数
- beg:开始迭代器
- end:结束迭代器
- value:统计的元素
4.2.5 count_if
按条件统计元素出现的个数
函数原型:
count_if(iterator beg, iterator end, _Pred);
- beg:开始迭代器
- end:结束迭代器
- _Pred:谓词
4.3 常用排序算法
4.3.1 sort
对容器内元素进行排序
函数原型:
sort(iterator beg, iterator end, _Pred);
- 对容器中数据进行排序,默认为升序
- beg:开始迭代器
- end:结束迭代器
- _Pred:谓词,提供排序规则,可有可无,无时默认为升序
4.3.2 random_shuffle
洗牌,指定范围内的元素随机调整次序
函数原型:
random_shuffle(iterator beg, iterator end);
- beg:开始迭代器
- end:结束迭代器
4.3.3 merge
将两个容器内的元素合并,并存储到另一个容器中,两个容器必须为有序的容器
函数原型:
merge(iterator beg1, iteratorend1, iterator beg2, iterator end2, iterator dest);
- beg1:容器1的开始迭代器
- beg2:容器1的结束迭代器
- end1:容器2的开始迭代器
- end2:容器2的结束迭代器
- dest:目标容器的开始迭代器
4.3.4 reverse
将容器内元素进行反转
函数原型:
reverse(iterator beg, iterator end);
- beg:开始迭代器
- end:结束迭代器
4.4 常用拷贝和替换算法
4.4.1 copy
将容器内指定范围的元素拷贝到另一个容器中
函数原型:
copy(iterator beg, iterator end, iterator dest);
- beg:开始迭代器
- end:结束迭代器
- dest:目标容器的开始迭代器
4.4.2 replace
将容器内指定范围内的旧元素修改为新元素
函数原型:
replace(iterator beg, iterator end, oldvalue, newvalue);
- beg:开始迭代器
- end:结束迭代器
- oldvalue:旧元素
- newvalue:新元素
4.4.3 replace_if
将区间内满足条件的元素,替换成指定元素
函数原型:
replace_if(iterator beg, iterator end, _Pred, newvalue);
- beg:开始迭代器
- end:结束迭代器
- _Pred:谓词
- newvalue:新元素
4.4.4 swap
互换两个容器内的元素
函数原型:
swap(container c1, container c2);
- container1:容器1
- container2:容器2
4.5 常用算数生成算法
算数生成算法属于小型算法,使用时包含头文件 #include<numeric>
4.5.1 accumulate
计算区间内 容器元素累加总和
函数原型:
accumulate(iterator bed, iterator end, value);
- beg:开始迭代器
- end:结束迭代器
- value:起始累加值
4.5.2 fill
向容器中填充指定数据
函数原型:
fill(iterator beg, iterator end, value);
- beg:开始迭代器
- end:结束迭代器
- value:待填充的值
4.6 常用集合算法
4.6.1 set_intersection
求两个容器集合的交集;
注意:两个容器必须为有序序列
函数原型:
set_intersection(interator beg1, interator end1, interator beg2, interator end2,interator dest);
- beg1:容器1的开始迭代器
- beg2:容器1的结束迭代器
- end1:容器2的开始迭代器
- end2:容器2的结束迭代器
- dest:目标容器的开始迭代器
4.6.2 set_union
求两个容器的并集
注意:两个容器集合必须为有序序列
set_union(interator beg1, interator end1, interator beg2, interator end2,interator dest);
- beg1:容器1的开始迭代器
- beg2:容器1的结束迭代器
- end1:容器2的开始迭代器
- end2:容器2的结束迭代器
- dest:目标容器的开始迭代器
4.6.3 set_difference
求两个容器集合的差集
注意:两个容器集合必须为有序序列
set_difference(interator beg1, interator end1, interator beg2, interator end2,interator dest);
- beg1:容器1的开始迭代器
- beg2:容器1的结束迭代器
- end1:容器2的开始迭代器
- end2:容器2的结束迭代器
- dest:目标容器的开始迭代器