✨博客主页 | ||
---|---|---|
何曾参静谧的博客 | ||
📌文章专栏 | ||
「C/C++」C/C++程序设计 | ||
📚全部专栏 | ||
「VS」Visual Studio | 「C/C++」C/C++程序设计 | 「UG/NX」BlockUI集合 |
「Win」Windows程序设计 | 「DSA」数据结构与算法 | 「UG/NX」NX二次开发 |
「QT」QT5程序设计 | 「File」数据文件格式 | 「PK」Parasolid函数说明 |
目录
- std::set容器深度解析
- 1. 引用头文件
- 2. 注意事项
- 3. 函数构造与对象初始化
- 4. 元素访问
- 5. 迭代器
- 6. 容器修改器
- 7. 元素比较
- 总结与应用场景
std::set容器深度解析
1. 引用头文件
在C++标准模板库(STL)中,std::set
是一个重要的关联容器,它提供了自动排序且元素唯一的存储机制。要使用std::set
,首先需要包含其对应的头文件:
#include <set>
2. 注意事项
- 元素唯一性:
std::set
中的元素是唯一的,不允许重复。 - 自动排序:元素会根据提供的比较函数(默认为
<
运算符)进行排序。 - 不支持随机访问:由于底层实现为红黑树,
std::set
不支持通过下标访问元素。 - 内存开销:红黑树的实现导致
std::set
的内存开销相对较大。
3. 函数构造与对象初始化
std::set
提供了多种构造函数来初始化对象:
- 默认构造函数:创建一个空的
set
容器。 - 拷贝构造函数:用另一个
set
容器来初始化新的set
容器。 - 赋值构造函数:通过赋值运算符从一个
set
容器创建另一个set
容器。 - 初始化列表构造函数:使用初始化列表来初始化
set
容器。 - 迭代器范围构造函数:使用两个迭代器(指向容器或其他序列的起始和结束位置)来初始化
set
容器。
示例代码:
#include <set>
#include <iostream>
int main() {
// 默认构造函数
std::set<int> s1;
// 初始化列表构造函数
std::set<int> s2 = {5, 3, 8, 1, 9, 9}; // 这里的9不会重复出现
// 拷贝构造函数
std::set<int> s3(s2);
// 迭代器范围构造函数(假设有一个数组)
int arr[] = {2, 4, 6, 7, 0};
std::set<int> s4(arr, arr + 5);
// 输出set元素(自动排序)
for (const auto& elem : s4) {
std::cout << elem << " ";
}
std::cout << std::endl;
return 0;
}
4. 元素访问
由于std::set
不支持随机访问,因此不能通过下标访问元素。但可以使用成员函数如find
、count
、lower_bound
和upper_bound
来查找元素。
示例代码:
#include <set>
#include <iostream>
int main() {
std::set<int> s = {1, 2, 3, 4, 5};
// 使用find查找元素
auto it = s.find(3);
if (it != s.end()) {
std::cout << "Found 3 in the set." << std::endl;
} else {
std::cout << "3 not found in the set." << std::endl;
}
// 使用count检查元素是否存在(对于set,count要么为0要么为1)
if (s.count(6) == 0) {
std::cout << "6 not found in the set." << std::endl;
}
return 0;
}
5. 迭代器
std::set
的迭代器是双向迭代器,支持向前和向后遍历容器中的元素。由于std::set
的迭代器与底层红黑树结构相关联,因此在插入和删除操作时(除了被删除的迭代器外),其余迭代器仍然有效。
#include <iostream>
#include <set>
int main() {
std::set<int> mySet = {1, 2, 3, 4, 5};
// 使用范围for循环遍历set
for (const int& elem : mySet) {
std::cout << elem << " ";
}
std::cout << std::endl;
// 使用迭代器遍历set
for (std::set<int>::iterator it = mySet.begin(); it != mySet.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 迭代器遍历并删除对象
for (auto it = mySet.begin(); it != mySet.end();) {
if (*it % 2 == 0) { // 删除所有偶数元素作为示例
it = mySet.erase(it); // erase返回指向下一个元素的迭代器
} else {
std::cout << *it << " ";
++it; // 只有当没有删除元素时才递增迭代器
}
}
std::cout << std::endl;
return 0;
}
6. 容器修改器
std::set
提供了多种成员函数来修改容器:
- insert:插入元素(如果元素已存在,则插入失败)。
- erase:删除元素。
- clear:清除所有元素。
- swap:交换两个
set
容器的元素。
#include <set>
#include <iostream>
int main() {
std::set<int> s = {1, 2, 3, 4, 5};
// 插入元素
auto result = s.insert(6);
if (result.second) {
std::cout << "Inserted 6 successfully." << std::endl;
} else {
std::cout << "6 already exists in the set." << std::endl;
}
// 删除元素
s.erase(3);
// 输出修改后的set元素
for (const auto& elem : s) {
std::cout << elem << " ";
}
std::cout << std::endl;
// 清除所有元素
s.clear();
return 0;
}
7. 元素比较
std::set
中的元素是根据提供的比较函数(默认为<
运算符)进行排序的。因此,可以直接使用比较运算符来比较std::set
中的元素或迭代器指向的元素。
总结与应用场景
std::set
是一个功能强大的关联容器,它提供了自动排序和元素唯一的特性。然而,由于红黑树的实现,其内存开销相对较大,且不支持随机访问。std::set
适用于需要快速查找、插入和删除唯一元素的场景,如:
- 去重和排序:将一组数据去重并排序。
- 元素查找:在大量数据中快速查找某个元素是否存在。
- 集合运算:如并集、交集、差集等集合运算(可以使用STL中的算法如
std::set_union
、std::set_intersection
、std::set_difference
等)。 - 需要保持元素有序性的场景:如任务调度、资源管理等。
通过合理使用std::set
容器,可以显著提高程序的效率和可靠性,特别是在需要处理唯一性和排序性的场景中。