set是C++标准模板库中的关联式容器,它的底层基于红黑树实现,因此在插入元素时会自动按照既定规则排序,并且会保证容器内不会出现重复的元素,这两个特性让它在很多数据处理场景中都能发挥重要作用。
set容器的基本定义
使用set容器前需要包含头文件<set>,定义set对象时可以指定元素类型,默认情况下会按照元素的小于号规则进行升序排序。如果需要自定义排序规则,也可以在定义时传入比较函数。
#include <set>
#include <iostream>
using namespace std;
int main() {
// 定义存储int类型的set,默认升序排序
set<int> intSet;
// 定义存储string类型的set,默认按字典序升序排序
set<string> strSet;
return 0;
}
set容器的常用操作
插入元素
使用insert方法向set中插入元素,插入重复元素时会被自动忽略,插入后会自动调整顺序保持排序规则。
#include <set>
#include <iostream>
using namespace std;
int main() {
set<int> numSet;
// 插入元素,重复插入3只会保留一个
numSet.insert(3);
numSet.insert(1);
numSet.insert(2);
numSet.insert(3);
// 遍历输出结果,会是1 2 3的顺序
for (int num : numSet) {
cout << num << " ";
}
cout << endl; // 输出:1 2 3
return 0;
}
遍历元素
set容器支持迭代器遍历,也支持C++11之后的范围for循环遍历,遍历的顺序就是set当前的排序顺序。
#include <set>
#include <iostream>
using namespace std;
int main() {
set<int> numSet = {5, 2, 8, 2, 5};
// 迭代器遍历
cout << "迭代器遍历结果:";
for (set<int>::iterator it = numSet.begin(); it != numSet.end(); ++it) {
cout << *it << " ";
}
cout << endl;
// 范围for遍历
cout << "范围for遍历结果:";
for (int num : numSet) {
cout << num << " ";
}
cout << endl;
return 0;
}
查找与删除元素
使用find方法可以查找指定元素,返回对应的迭代器,如果没找到则返回end()迭代器。使用erase方法可以删除指定元素或者指定迭代器位置的元素。
#include <set>
#include <iostream>
using namespace std;
int main() {
set<int> numSet = {1, 3, 5, 7, 9};
// 查找元素5
auto it = numSet.find(5);
if (it != numSet.end()) {
cout << "找到元素5" << endl;
// 删除元素5
numSet.erase(it);
}
// 删除不存在的元素不会报错
numSet.erase(10);
// 输出删除后的结果
cout << "删除后的元素:";
for (int num : numSet) {
cout << num << " ";
}
cout << endl; // 输出:1 3 7 9
return 0;
}
利用set实现数组去重与排序
set的自动去重和排序特性可以很方便地实现数组去重后排序的需求,不需要手动写排序和去重逻辑。
#include <set>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> arr = {4, 2, 7, 2, 4, 9, 1, 7};
// 将数组元素插入set,自动去重排序
set<int> resultSet(arr.begin(), arr.end());
// 输出结果
cout << "去重排序后的结果:";
for (int num : resultSet) {
cout << num << " ";
}
cout << endl; // 输出:1 2 4 7 9
return 0;
}
自定义set的排序规则
默认情况下set按照升序排序,如果需要降序或者其他自定义排序规则,可以在定义set时传入比较结构体或者函数对象。
#include <set>
#include <iostream>
using namespace std;
// 自定义降序比较规则
struct CompareDesc {
bool operator()(int a, int b) const {
return a > b;
}
};
int main() {
// 定义降序排序的set
set<int, CompareDesc> descSet;
descSet.insert(3);
descSet.insert(1);
descSet.insert(2);
descSet.insert(3);
// 遍历输出,会是3 2 1的顺序
cout << "降序排序结果:";
for (int num : descSet) {
cout << num << " ";
}
cout << endl; // 输出:3 2 1
return 0;
}
set容器的注意事项
- set中的元素是常量,不能通过迭代器修改元素的值,否则会破坏红黑树的排序结构。
- set的插入、删除、查找操作的时间复杂度都是O(log n),效率较高。
- 如果需要存储重复元素,可以使用multiset容器,它的用法和set基本一致,只是允许重复元素存在。