type
status
date
slug
summary
tags
category
icon
password
comment
2024.11.27
给C++这个部分收尾一下,拖了太久了~主要介绍STL中容器和一些算法
一、array 详解基本特点头文件成员函数详解1. 迭代器相关函数2. 元素访问函数3. 容量相关函数4. 修改器函数5. 非成员函数特性和注意事项使用场景二、std::vector 详解基本特点头文件成员函数详解1. 迭代器相关函数2. 元素访问函数3. 容量相关函数4. 修改器函数5. 与 STL 算法结合使用特性和注意事项使用场景三、std::deque 详解基本特点头文件成员函数详解1. 迭代器相关函数2. 元素访问函数3. 容量相关函数4. 修改器函数5. 与 STL 算法结合使用特性和注意事项使用场景四、std::forward_list 详解基本特点头文件成员函数详解1. 迭代器相关函数2. 容量相关函数3. 元素访问函数4. 修改器函数5. 链表操作6. 与 STL 算法结合使用特性和注意事项使用场景五、std::list 详解基本特点头文件成员函数详解1. 迭代器相关函数2. 容量相关函数3. 元素访问函数4. 修改器函数5. 链表操作6. 与 STL 算法结合使用特性和注意事项使用场景六、std::set 详解基本特点头文件成员函数详解1. 迭代器相关函数2. 容量相关函数3. 元素操作函数4. 查找操作函数5. 比较器6. 与 STL 算法结合使用特性和注意事项使用场景进一步说明十八、std::bitset详解头文件特点常用成员函数按位操作支持示例代码十九、std::pair详解头文件特点常用成员常用函数示例代码二十、STL中常用算法STL 中常用算法库详解1. 排序算法2. 查找算法3. 修改算法4. 数值计算算法5. 集合操作算法6. 其他通用算法
一、array
详解
std::array
是 C++ 标准模板库(STL)中的一个容器,提供了静态大小的数组封装。与传统的 C 风格数组相比,它在类型安全和功能性方面有更大的提升。基本特点
- 静态大小:
std::array
的大小在编译时确定,不能动态调整。
- 高效性:内部实现是一个 C 风格的数组,性能几乎没有额外开销。
- 接口丰富:提供了 STL 容器的统一接口,例如迭代器、容量操作、元素访问等。
- 类型安全:支持类型检查和范围检查(通过
at()
方法)。
头文件
声明和初始化
成员函数详解
1. 迭代器相关函数
begin()
和cbegin()
:返回指向第一个元素的迭代器或常量迭代器。
end()
和cend()
:返回指向末尾后一个位置的迭代器或常量迭代器。
rbegin()
和crbegin()
:返回反向迭代器指向最后一个元素。
rend()
和crend()
:返回反向迭代器指向第一个元素之前的位置。
示例:
2. 元素访问函数
at(size_t pos)
:安全访问指定位置的元素,超出范围会抛出std::out_of_range
异常。
operator[]
:快速访问指定位置的元素,不检查范围。
front()
:返回第一个元素的引用。
back()
:返回最后一个元素的引用。
data()
:返回指向数组的指针,可以与 C 风格代码兼容。
示例:
3. 容量相关函数
size()
:返回数组的大小。
max_size()
:返回数组的最大大小,通常等于size()
。
empty()
:检查容器是否为空。
示例:
4. 修改器函数
fill(const T& value)
:将数组的每个元素设置为指定值。
swap(std::array& other)
:交换两个数组的内容。
示例:
5. 非成员函数
std::get<N>(array)
:访问数组中索引为N
的元素,编译期检查。
- 比较运算符:
==
,!=
,<
,>
,<=
,>=
。
示例:
特性和注意事项
- 大小固定:
std::array
的大小必须在编译时确定,因此适合静态分配的场景。
- 与传统数组的区别:
- 提供 STL 接口,方便与其他容器交互。
- 支持范围检查和标准库功能。
- 与动态容器的区别:
- 不支持动态扩展(如
std::vector
)。 - 性能更高,没有动态分配的开销。
使用场景
- 数组大小在编译时已知且不会改变的场景。
- 性能要求较高时,
std::array
提供了类似 C 风格数组的效率,但安全性更高。
- 需要与 STL 容器或算法结合使用时。
二、std::vector
详解
std::vector
是 C++ 标准模板库中最常用的动态数组容器,支持动态大小调整。与 std::array
不同,std::vector
的大小在运行时可以灵活扩展或收缩。基本特点
- 动态大小:支持自动扩展和收缩。
- 连续内存:存储在一块连续内存中,可与 C 风格数组兼容。
- 高效访问:提供常数时间复杂度的随机访问(通过下标操作符)。
- 丰富功能:支持 STL 迭代器、算法、容量管理等功能。
- 自动管理内存:容器会自动分配和释放内存,避免手动管理。
头文件
声明和初始化
成员函数详解
1. 迭代器相关函数
begin()
和cbegin()
:返回指向第一个元素的迭代器或常量迭代器。
end()
和cend()
:返回指向末尾后一个位置的迭代器或常量迭代器。
rbegin()
和crbegin()
:返回指向最后一个元素的反向迭代器。
rend()
和crend()
:返回指向第一个元素之前的反向迭代器。
示例:
2. 元素访问函数
at(size_t pos)
:安全访问指定位置的元素,超出范围抛出异常。
operator[]
:快速访问指定位置的元素,不检查范围。
front()
:返回第一个元素的引用。
back()
:返回最后一个元素的引用。
data()
:返回指向底层数组的指针。
示例:
3. 容量相关函数
size()
:返回当前元素个数。
max_size()
:返回容器支持的最大元素数量。
capacity()
:返回当前分配的存储容量。
empty()
:检查容器是否为空。
reserve(size_t n)
:预留至少n
个容量,避免频繁重新分配。
shrink_to_fit()
:释放未使用的内存,减少内存占用。
示例:
4. 修改器函数
clear()
:移除所有元素。
insert(iterator pos, value)
:在指定位置插入元素。
insert(iterator pos, count, value)
:在指定位置插入多个相同元素。
erase(iterator pos)
:删除指定位置的元素。
erase(iterator first, iterator last)
:删除指定范围的元素。
push_back(const T& value)
:在末尾添加元素。
emplace_back(args...)
:在末尾直接构造元素。
pop_back()
:移除末尾元素。
resize(size_t n)
:调整大小,自动填充新元素为默认值。
resize(size_t n, const T& value)
:调整大小,新元素填充为指定值。
swap(vector& other)
:交换两个容器的内容。
示例:
5. 与 STL 算法结合使用
由于
std::vector
提供迭代器接口,可以与 STL 算法无缝结合:特性和注意事项
- 内存管理:
std::vector
使用动态分配内存,可能会因频繁的扩展导致性能下降。提前使用reserve()
可优化。
- 线程安全性:
std::vector
不是线程安全的,需要外部同步。
- 性能:
- 随机访问时间复杂度为 。
- 插入或删除的时间复杂度通常为 ,尤其是中间位置的操作。
- 与 C 风格数组的兼容:可以通过
data()
函数获得底层数组的指针,与旧代码或 C 库交互。
使用场景
- 当需要动态调整数组大小时,
std::vector
是首选。
- 适合对随机访问性能有要求的场景。
- 常用于集合操作、排序、查找和通用数据存储。
三、std::deque
详解
std::deque
(双端队列)是 C++ 标准模板库中的动态序列容器,与 std::vector
类似,但它在两端的插入和删除操作效率更高。deque
是 “double-ended queue” 的简称。基本特点
- 双端操作高效:在两端插入或删除元素的时间复杂度为 。
- 动态大小:支持动态扩展和收缩。
- 非连续内存:不同于
std::vector
的连续存储,std::deque
由多个连续的小块内存组成。
- 高效访问:随机访问的时间复杂度为 ,但比
std::vector
稍慢。
- 灵活性:适合频繁在两端插入或删除元素的场景。
头文件
声明和初始化
成员函数详解
1. 迭代器相关函数
begin()
和cbegin()
:返回指向第一个元素的迭代器或常量迭代器。
end()
和cend()
:返回指向末尾后一个位置的迭代器或常量迭代器。
rbegin()
和crbegin()
:返回反向迭代器,指向最后一个元素。
rend()
和crend()
:返回反向迭代器,指向第一个元素之前的位置。
示例:
2. 元素访问函数
at(size_t pos)
:安全访问指定位置的元素,超出范围会抛出异常。
operator[]
:快速访问指定位置的元素,不检查范围。
front()
:返回第一个元素的引用。
back()
:返回最后一个元素的引用。
示例:
3. 容量相关函数
size()
:返回当前元素个数。
max_size()
:返回容器支持的最大元素数量。
empty()
:检查容器是否为空。
shrink_to_fit()
:调整容量,减少内存浪费(实现可能无效,依赖具体标准库)。
示例:
4. 修改器函数
clear()
:移除所有元素。
insert(iterator pos, value)
:在指定位置插入元素。
insert(iterator pos, count, value)
:在指定位置插入多个相同元素。
erase(iterator pos)
:删除指定位置的元素。
erase(iterator first, iterator last)
:删除指定范围的元素。
push_back(const T& value)
:在末尾添加元素。
push_front(const T& value)
:在开头添加元素。
emplace_back(args...)
:在末尾直接构造元素。
emplace_front(args...)
:在开头直接构造元素。
pop_back()
:移除末尾元素。
pop_front()
:移除开头元素。
resize(size_t n)
:调整大小,自动填充新元素为默认值。
resize(size_t n, const T& value)
:调整大小,新元素填充为指定值。
swap(deque& other)
:交换两个容器的内容。
示例:
5. 与 STL 算法结合使用
由于
std::deque
提供迭代器接口,可以与 STL 算法无缝结合:特性和注意事项
- 与
std::vector
的区别: std::deque
支持高效的双端操作,适合频繁在两端插入或删除元素的场景。std::vector
在末尾插入和删除时效率更高。std::vector
使用连续内存,适合与低级 C 风格代码兼容;std::deque
使用分块存储。
- 性能:
- 随机访问时间复杂度为 ,但通常比
std::vector
略慢。 - 两端插入或删除操作时间复杂度为 。
- 与 C 风格数组的兼容性:
std::deque
不支持直接返回底层数组指针(因为其内存分块实现)。
使用场景
- 当需要频繁在两端插入或删除元素时,例如队列、缓冲区。
- 随机访问要求不高,但需要灵活扩展容量的场景。
- 更高效的双端操作要求。
四、std::forward_list
详解
std::forward_list
是 C++ 标准模板库中的单向链表容器,提供了一种轻量级的数据结构。与 std::list
不同,它仅支持单向链接,内存开销较低,适合某些特定场景。基本特点
- 单向链表:每个节点只存储一个指向下一个节点的指针。
- 高效插入和删除:在链表头部或已知位置后的插入与删除操作时间复杂度为 。
- 轻量级:由于单向链接的特性,相较于双向链表 (
std::list
),内存开销更小。
- 不支持随机访问:不能通过索引访问元素,必须使用迭代器进行遍历。
头文件
声明和初始化
成员函数详解
1. 迭代器相关函数
begin()
和cbegin()
:返回指向第一个元素的迭代器或常量迭代器。
end()
和cend()
:返回指向末尾后一个位置的迭代器或常量迭代器。
示例:
2. 容量相关函数
empty()
:检查容器是否为空。
max_size()
:返回容器支持的最大元素数量。
示例:
3. 元素访问函数
std::forward_list
由于是单向链表,不支持直接的随机访问,也没有 at()
或 operator[]
等操作,需通过迭代器访问。示例:
4. 修改器函数
clear()
:移除所有元素。
insert_after(iterator pos, value)
:在指定位置之后插入一个元素。
insert_after(iterator pos, count, value)
:在指定位置之后插入多个相同元素。
erase_after(iterator pos)
:删除指定位置之后的单个元素。
erase_after(iterator first, iterator last)
:删除指定范围的元素。
push_front(const T& value)
:在链表头部插入一个元素。
emplace_front(args...)
:在链表头部直接构造元素。
pop_front()
:移除链表头部的元素。
resize(size_t n)
:调整大小,自动填充新元素为默认值。
resize(size_t n, const T& value)
:调整大小,新元素填充为指定值。
swap(forward_list& other)
:交换两个链表的内容。
示例:
5. 链表操作
merge(forward_list& other)
:合并两个有序链表,other
变为空。
remove(const T& value)
:删除所有等于指定值的元素。
remove_if(predicate)
:删除满足条件的所有元素。
reverse()
:反转链表中的元素顺序。
sort()
:对链表中的元素排序。
unique()
:移除相邻的重复元素。
示例:
6. 与 STL 算法结合使用
std::forward_list
支持与部分 STL 算法结合,但由于其单向迭代特性,不支持随机访问相关算法:特性和注意事项
- 单向链表特性:
- 插入和删除操作比
std::vector
或std::deque
更高效。 - 不支持随机访问,所有访问操作都需要通过迭代器完成。
- 与
std::list
的区别: std::forward_list
是单向链表,内存占用更少。std::list
是双向链表,支持从任意位置的高效插入和删除。
- 性能:
- 插入或删除时间复杂度为 ,适用于频繁动态修改的场景。
- 遍历或查找时间复杂度为 ,不适合需要频繁随机访问的场景。
使用场景
- 适合需要高效头部插入或删除元素的场景。
- 适合内存受限但仍需链表特性的应用(例如嵌入式开发)。
- 适用于对链表操作有需求但不需要双向链表特性的场景。
五、std::list
详解
std::list
是 C++ 标准模板库中的双向链表容器。与 std::forward_list
不同,std::list
提供了双向链接的功能,允许从任意位置进行高效插入和删除操作。基本特点
- 双向链表:每个节点存储前驱和后继的指针,可以从任意位置向前或向后遍历。
- 高效的插入和删除:在任意位置插入或删除元素的时间复杂度为 。
- 动态大小:支持动态扩展和收缩。
- 不支持随机访问:不能通过索引访问元素,必须使用迭代器进行遍历。
- 内存占用较高:由于双向链接的特性,每个节点比
std::forward_list
需要更多的内存。
头文件
声明和初始化
成员函数详解
1. 迭代器相关函数
begin()
和cbegin()
:返回指向第一个元素的迭代器或常量迭代器。
end()
和cend()
:返回指向末尾后一个位置的迭代器或常量迭代器。
rbegin()
和crbegin()
:返回反向迭代器,指向最后一个元素。
rend()
和crend()
:返回反向迭代器,指向第一个元素之前的位置。
示例:
2. 容量相关函数
size()
:返回当前元素个数。
max_size()
:返回容器支持的最大元素数量。
empty()
:检查容器是否为空。
示例:
3. 元素访问函数
front()
:返回第一个元素的引用。
back()
:返回最后一个元素的引用。
示例:
4. 修改器函数
clear()
:移除所有元素。
insert(iterator pos, value)
:在指定位置插入元素。
insert(iterator pos, count, value)
:在指定位置插入多个相同元素。
erase(iterator pos)
:删除指定位置的元素。
erase(iterator first, iterator last)
:删除指定范围的元素。
push_back(const T& value)
:在链表末尾插入元素。
push_front(const T& value)
:在链表头部插入元素。
emplace_back(args...)
:在链表末尾直接构造元素。
emplace_front(args...)
:在链表头部直接构造元素。
pop_back()
:移除链表末尾的元素。
pop_front()
:移除链表头部的元素。
resize(size_t n)
:调整大小,自动填充新元素为默认值。
resize(size_t n, const T& value)
:调整大小,新元素填充为指定值。
swap(list& other)
:交换两个链表的内容。
示例:
5. 链表操作
merge(list& other)
:合并两个有序链表,other
变为空。
remove(const T& value)
:删除所有等于指定值的元素。
remove_if(predicate)
:删除满足条件的所有元素。
reverse()
:反转链表中的元素顺序。
sort()
:对链表中的元素排序。
unique()
:移除相邻的重复元素。
示例:
6. 与 STL 算法结合使用
std::list
支持与 STL 算法结合,但由于其链表特性,某些算法可能效率较低:特性和注意事项
- 双向链表特性:
- 插入和删除操作比
std::vector
或std::deque
更高效,尤其是在中间位置。 - 支持双向遍历,适合需要从两端或中间插入删除的场景。
- 与
std::vector
的区别: std::list
插入和删除效率高,但随机访问效率低。std::vector
随机访问效率高,但在中间插入和删除效率低。
- 与
std::forward_list
的区别: std::list
是双向链表,支持从后向前遍历。std::forward_list
是单向链表,更轻量级,但操作有限。
使用场景
- 当需要频繁在中间插入或删除元素时,
std::list
是首选。
- 适合需要从两端进行操作且随机访问要求较低的场景。
- 在需要高效排序、合并或反转链表时。
六、std::set
详解
std::set
是 C++ 标准模板库中的有序容器,基于红黑树实现,提供高效的元素管理和有序存储。std::set
中的元素是唯一的,自动按顺序排列。基本特点
- 元素唯一性:
std::set
不允许重复元素。
- 自动排序:元素按特定的比较规则(默认升序)自动排序。
- 底层实现:基于红黑树,保证常数的插入、删除和查找时间复杂度为 。
- 不可直接修改元素值:由于元素位置依赖排序规则,必须先删除旧元素,再插入新值。
头文件
声明和初始化
成员函数详解
1. 迭代器相关函数
begin()
和cbegin()
:返回指向第一个元素的迭代器或常量迭代器。
end()
和cend()
:返回指向末尾后一个位置的迭代器或常量迭代器。
rbegin()
和crbegin()
:返回反向迭代器,指向最后一个元素。
rend()
和crend()
:返回反向迭代器,指向第一个元素之前的位置。
示例:
2. 容量相关函数
empty()
:检查容器是否为空。
size()
:返回当前元素个数。
max_size()
:返回容器支持的最大元素数量。
示例:
3. 元素操作函数
insert(const T& value)
:插入元素,返回迭代器和布尔值,布尔值指示是否成功插入。
emplace(args...)
:在容器中直接构造元素。
erase(iterator pos)
:删除指定位置的元素。
erase(const T& value)
:删除指定值的元素,返回删除的元素个数。
erase(iterator first, iterator last)
:删除指定范围内的元素。
clear()
:移除所有元素。
swap(set& other)
:交换两个集合的内容。
示例:
4. 查找操作函数
find(const T& value)
:查找指定值的元素,返回迭代器,若未找到则返回end()
。
count(const T& value)
:返回指定值的出现次数(对于std::set
,结果始终为 0 或 1)。
lower_bound(const T& value)
:返回指向第一个不小于value
的迭代器。
upper_bound(const T& value)
:返回指向第一个大于value
的迭代器。
equal_range(const T& value)
:返回等于value
的元素范围(pair<iterator, iterator>
)。
示例:
5. 比较器
key_comp()
:返回用于比较键的比较器对象。
value_comp()
:返回用于比较值的比较器对象。
示例:
6. 与 STL 算法结合使用
std::set
提供了迭代器接口,可以与 STL 算法结合:特性和注意事项
- 唯一性:
- 插入重复元素时,
insert()
会返回插入失败的状态。
- 有序性:
- 默认按升序排列,可通过自定义比较器改变排序规则。
- 效率:
- 查找、插入、删除操作的时间复杂度为 。
- 不支持随机访问。
- 迭代器稳定性:
- 插入和删除操作不会使其他迭代器失效。
使用场景
- 需要保持元素唯一性并保持有序的场景。
- 需要高效查找、插入和删除操作时。
- 适合需要自动排序但无随机访问需求的集合操作。
功能分类 | 支持的函数 | 顺序容器 | 关联容器 | 无序关联容器 | 容器适配器 |
构造与销毁 | 构造函数 | ✅ array ,vector ,deque ,list | ✅ set ,map ,multiset ,multimap | ✅ unordered_set ,unordered_map ,
unordered_multiset,unordered_multimap | ✅ stack ,queue ,priority_queue |
ㅤ | 析构函数 | ✅ | ✅ | ✅ | ✅ |
ㅤ | operator= | ✅ | ✅ | ✅ | ❌ |
ㅤ | assign | ✅ | ❌ | ❌ | ❌ |
迭代器支持 | begin() / end() | ✅ 支持 | ✅ 支持 | ✅ 支持 | ❌ 不支持 |
ㅤ | cbegin() / cend() | ✅ 支持 | ✅ 支持 | ✅ 支持 | ❌ 不支持 |
ㅤ | rbegin() / rend() | ✅ 支持 | ✅ 支持 | ❌ 不支持 | ❌ 不支持 |
ㅤ | crbegin() / crend() | ✅ 支持 | ✅ 支持 | ❌ 不支持 | ❌ 不支持 |
容量管理 | size() / max_size() | ✅ 支持 | ✅ 支持 | ✅ 支持 | ✅ 支持 |
ㅤ | empty() | ✅ 支持 | ✅ 支持 | ✅ 支持 | ✅ 支持 |
ㅤ | capacity() | ✅ ( vector , deque ) | ❌ | ❌ | ❌ |
ㅤ | reserve() | ✅ ( vector ) | ❌ | ✅ 支持 | ❌ |
ㅤ | resize() | ✅ 支持 | ❌ | ❌ | ❌ |
元素访问 | at() | ✅ ( vector , deque ) | ❌ | ❌ | ❌ |
ㅤ | operator[] | ✅ ( vector , deque ) | ✅ ( map ) | ✅ ( unordered_map ) | ❌ |
ㅤ | front() / back() | ✅ 支持 | ❌ | ❌ | ✅( stack ,queue 的变体) |
修改器 | insert() | ✅ 支持 | ✅ 支持 | ✅ 支持 | ❌ |
ㅤ | emplace() | ✅ 支持 | ✅ 支持 | ✅ 支持 | ✅(部分支持) |
ㅤ | erase() | ✅ 支持 | ✅ 支持 | ✅ 支持 | ❌ |
ㅤ | push_back() / pop_back() | ✅ ( vector , deque ) | ❌ | ❌ | ❌ |
ㅤ | push_front() / pop_front() | ✅ ( deque , list ) | ❌ | ❌ | ✅( queue 支持) |
ㅤ | clear() | ✅ 支持 | ✅ 支持 | ✅ 支持 | ❌ |
ㅤ | swap() | ✅ 支持 | ✅ 支持 | ✅ 支持 | ✅ |
排序操作 | sort() | ✅ ( list ) | ❌ | ❌ | ❌ |
ㅤ | merge() | ✅ ( list ) | ✅ 支持 | ❌ | ❌ |
ㅤ | unique() | ✅ ( list ) | ❌ | ❌ | ❌ |
ㅤ | reverse() | ✅ ( list ) | ❌ | ❌ | ❌ |
链表特性 | splice() / splice_after() | ✅ ( list , forward_list ) | ❌ | ❌ | ❌ |
查找操作 | find() | ❌ | ✅ 支持 | ✅ 支持 | ❌ |
ㅤ | count() | ✅ ( list ) | ✅ 支持 | ✅ 支持 | ❌ |
ㅤ | lower_bound() / upper_bound() | ❌ | ✅ 支持 | ❌ | ❌ |
ㅤ | equal_range() | ❌ | ✅ 支持 | ✅ 支持 | ❌ |
ㅤ | contains() | ❌ | ✅(C++20 起) | ✅(C++20 起) | ❌ |
观察器 | key_comp() / value_comp() | ❌ | ✅ 支持 | ❌ | ❌ |
哈希操作 | bucket_count() / bucket() | ❌ | ❌ | ✅ 支持 | ❌ |
ㅤ | load_factor() / max_load_factor() | ❌ | ❌ | ✅ 支持 | ❌ |
适配器特性 | top() / front() / back() | ❌ | ❌ | ❌ | ✅( stack ,queue 支持) |
ㅤ | push() / pop() | ❌ | ❌ | ❌ | ✅ 支持 |
分配器 | get_allocator() | ✅ 支持 | ✅ 支持 | ✅ 支持 | ❌ |
进一步说明
- 顺序容器 提供丰富的修改器和迭代器功能,适合动态大小和顺序存储的需求,操作简单但遍历复杂度取决于实现。
- 关联容器 适合存储有序键值对,支持高效查找,但随机访问性能较差。
- 无序关联容器 是关联容器的哈希版本,适合需要快速插入和查找的场景,但对顺序没有要求。
- 容器适配器 提供特定功能(如栈、队列),其功能受到严格限制以适应目标用途。
十八、std::bitset
详解
std::bitset
是 C++ 标准库中的一个容器类,用于管理和操作固定大小的位集合。它提供了一种高效的方式来存储和操作位数据。头文件
特点
- 固定大小:位集合大小在编译时确定,不能动态调整。
- 高效存储:每个位占用 1 位内存,适合处理布尔数据。
- 功能丰富:支持按位操作、位翻转、位访问等操作。
- 适合位操作应用:如位掩码、布尔向量、状态集合等。
构造与初始化
常用成员函数
函数 | 描述 | 示例 |
size() | 返回位集合的大小。 | b1.size(); |
count() | 返回位集合中值为 1 的位数。 | b1.count(); |
any() | 检查是否至少有一个位为 1。 | b1.any(); |
none() | 检查是否所有位都为 0。 | b1.none(); |
all() | 检查是否所有位都为 1。 | b1.all(); |
set() | 将所有位设置为 1,或设置指定位置为 1。 | b1.set(); b1.set(2); |
reset() | 将所有位设置为 0,或设置指定位置为 0。 | b1.reset(); b1.reset(2); |
flip() | 翻转所有位或指定位置的位。 | b1.flip(); b1.flip(2); |
test() | 检查指定位置的位是否为 1。 | b1.test(2); |
operator[] | 返回指定位置位的值(只读访问)。 | b1[2]; |
to_string() | 返回 bitset 的字符串表示。 | b1.to_string(); |
to_ulong() | 将 bitset 转换为无符号长整数(位数不超过 unsigned long 大小)。 | b1.to_ulong(); |
按位操作支持
std::bitset
支持按位操作符(&
, |
, ^
, ~
)和移位操作符(<<
, >>
)。示例:
示例代码
十九、std::pair
详解
std::pair
是 C++ 标准库中的一个简单容器,用于存储两个值(称为 first 和 second)。这两个值可以是不同类型。头文件
特点
- 用于将两个关联值打包成一个单元。
- 常用于返回多个值的函数。
- 提供成员函数和运算符重载。
构造与初始化
常用成员
成员变量 | 描述 | 示例 |
first | 存储第一个值。 | p1.first = 10; |
second | 存储第二个值。 | p1.second = "example"; |
常用函数
函数 | 描述 | 示例 |
make_pair | 创建一个 pair ,推导元素类型。 | auto p = std::make_pair(1, "text"); |
operator== | 检查两个 pair 是否相等。 | if (p1 == p2) {...} |
operator< | 按字典序比较两个 pair ,先比较 first ,若相等则比较 second 。 | if (p1 < p2) {...} |
示例代码
二十、STL中常用算法
STL 中常用算法库详解
C++ 标准模板库(STL)中提供了丰富的算法库,用于操作容器中的元素。算法库主要定义在头文件
<algorithm>
和 <numeric>
中,包括排序、查找、修改、数值计算等多种算法。以下是 STL 算法库中常用算法的分类及其详细说明:
1. 排序算法
算法 | 描述 | 复杂度 | 示例 |
sort | 对范围内元素进行升序排序,支持自定义比较函数。 | std::sort(v.begin(), v.end()); | |
stable_sort | 稳定排序,保证相等元素的相对顺序。 | std::stable_sort(v.begin(), v.end()); | |
partial_sort | 对范围内前 k 个元素排序,其他元素顺序不定。 | std::partial_sort(v.begin(), v.begin() + k, v.end()); | |
nth_element | 将第 n 小的元素放到正确位置,左侧小于 n,右侧大于 n。 | std::nth_element(v.begin(), v.begin() + n, v.end()); | |
is_sorted | 检查范围内的元素是否已经按升序排列。 | bool sorted = std::is_sorted(v.begin(), v.end()); |
2. 查找算法
算法 | 描述 | 复杂度 | 示例 |
find | 查找范围内第一个等于指定值的元素,返回迭代器。 | auto it = std::find(v.begin(), v.end(), value); | |
find_if | 查找满足条件的第一个元素,返回迭代器。 | auto it = std::find_if(v.begin(), v.end(), predicate); | |
find_if_not | 查找第一个不满足条件的元素,返回迭代器。 | auto it = std::find_if_not(v.begin(), v.end(), predicate); | |
binary_search | 在有序范围内进行二分查找,返回是否找到指定值。 | bool found = std::binary_search(v.begin(), v.end(), value); | |
lower_bound | 返回第一个大于等于值的元素迭代器(在有序范围内)。 | auto it = std::lower_bound(v.begin(), v.end(), value); | |
upper_bound | 返回第一个大于值的元素迭代器(在有序范围内)。 | auto it = std::upper_bound(v.begin(), v.end(), value); | |
equal_range | 返回等于值的范围(两个迭代器)。 | auto range = std::equal_range(v.begin(), v.end(), value); |
3. 修改算法
算法 | 描述 | 复杂度 | 示例 |
copy | 将范围内的元素复制到另一个范围。 | std::copy(v.begin(), v.end(), dest.begin()); | |
copy_if | 将满足条件的元素复制到另一个范围。 | std::copy_if(v.begin(), v.end(), dest.begin(), predicate); | |
move | 将范围内的元素移动到另一个范围。 | std::move(v.begin(), v.end(), dest.begin()); | |
transform | 将范围内的元素通过函数变换后复制到另一个范围。 | std::transform(v.begin(), v.end(), dest.begin(), func); | |
replace | 将范围内等于某值的元素替换为另一个值。 | std::replace(v.begin(), v.end(), old_value, new_value); | |
replace_if | 替换满足条件的元素为指定值。 | std::replace_if(v.begin(), v.end(), predicate, new_value); | |
remove | 移动等于指定值的元素到范围末尾,不改变容器大小。 | auto it = std::remove(v.begin(), v.end(), value); | |
remove_if | 移动满足条件的元素到范围末尾,不改变容器大小。 | auto it = std::remove_if(v.begin(), v.end(), predicate); | |
unique | 移动相邻的重复元素到范围末尾,不改变容器大小。 | auto it = std::unique(v.begin(), v.end()); | |
reverse | 反转范围内的元素顺序。 | std::reverse(v.begin(), v.end()); | |
rotate | 将范围内的元素旋转。 | std::rotate(v.begin(), v.middle(), v.end()); |
4. 数值计算算法
算法 | 描述 | 复杂度 | 示例 |
accumulate | 计算范围内元素的累加和,可使用自定义操作。 | int sum = std::accumulate(v.begin(), v.end(), 0); | |
inner_product | 计算两个范围内元素的内积。 | int dot = std::inner_product(a.begin(), a.end(), b.begin(), 0); | |
adjacent_difference | 计算相邻元素的差值并存储到另一范围。 | std::adjacent_difference(v.begin(), v.end(), result.begin()); | |
partial_sum | 计算范围内的部分和(前缀和)。 | std::partial_sum(v.begin(), v.end(), result.begin()); | |
iota | 填充范围内的元素为连续递增值。 | std::iota(v.begin(), v.end(), 0); |
5. 集合操作算法
算法 | 描述 | 复杂度 | 示例 |
set_union | 计算两个范围的并集,结果存储到另一个范围。 | std::set_union(a.begin(), a.end(), b.begin(), b.end(), result.begin()); | |
set_intersection | 计算两个范围的交集,结果存储到另一个范围。 | std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), result.begin()); | |
set_difference | 计算两个范围的差集,结果存储到另一个范围。 | std::set_difference(a.begin(), a.end(), b.begin(), b.end(), result.begin()); | |
set_symmetric_difference | 计算两个范围的对称差集,结果存储到另一个范围。 | std::set_symmetric_difference(a.begin(), a.end(), b.begin(), b.end(), result.begin()); |
6. 其他通用算法
算法 | 描述 | 复杂度 | 示例 |
for_each | 对范围内的每个元素应用指定的操作。 | std::for_each(v.begin(), v.end(), [](int x){ std::cout << x; }); | |
min_element | 返回范围内最小元素的迭代器。 | auto it = std::min_element(v.begin(), v.end()); | |
max_element | 返回范围内最大元素的迭代器。 | auto it = std::max_element(v.begin(), v.end()); | |
minmax_element | 同时返回范围内最小和最大元素的迭代器( std::pair )。 | auto result = std::minmax_element(v.begin(), v.end()); | |
all_of | 检查范围内是否所有元素都满足条件。 | bool result = std::all_of(v.begin(), v.end(), [](int x){ return x > 0; }); | |
any_of | 检查范围内是否至少有一个元素满足条件。 | bool result = std::any_of(v.begin(), v.end(), [](int x){ return x > 0; }); | |
none_of | 检查范围内是否所有元素都不满足条件。 | bool result = std::none_of(v.begin(), v.end(), [](int x){ return x > 0; }); | |
equal | 检查两个范围内的元素是否相等(按顺序比较)。 | bool result = std::equal(v1.begin(), v1.end(), v2.begin()); | |
mismatch | 返回两个范围内首个不匹配的元素对的迭代器。 | auto result = std::mismatch(v1.begin(), v1.end(), v2.begin()); | |
lexicographical_compare | 按字典序比较两个范围,返回是否第一个范围小于第二个范围。 | bool result = std::lexicographical_compare(s1.begin(), s1.end(), s2.begin(), s2.end()); | |
swap_ranges | 交换两个范围的元素内容。 | std::swap_ranges(v1.begin(), v1.end(), v2.begin()); | |
shuffle | 将范围内的元素按随机顺序重新排列(需要随机数生成器)。 | std::shuffle(v.begin(), v.end(), std::default_random_engine()); |
- 作者:Samuel Hu
- 链接:http://www.hjw-aihub.cn/technology/STL4C%2B%2B
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。