
| ✨博客主页 | ||
|---|---|---|
| 何曾参静谧的博客 | ||
| 📌文章专栏 | ||
| 「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容器,可以显著提高程序的效率和可靠性,特别是在需要处理唯一性和排序性的场景中。



















