std::set 使用总结

本文解析了set容器的特点,强调其为有序容器,并指出对于set这样的有序容器不能进行元素的赋值操作。

set是有序容器,不可以对有序容器(如set、map)的元素执行赋值操作

 

`std::set` 是 C++ 标准模板库(STL)中的一个关联容器,用于存储唯一元素并按特定顺序排列(默认升序)。以下是 `std::set` 的详细用法和示例: --- ### **1. 基本用法** #### **(1) 包含头文件** ```cpp #include <set> ``` #### **(2) 创建 `std::set`** ```cpp std::set<int> s; // 默认升序 std::set<int, std::greater<int>> s_desc; // 降序 ``` #### **(3) 插入元素** ```cpp s.insert(10); s.insert(20); s.insert(10); // 重复元素不会被插入 ``` #### **(4) 删除元素** ```cpp s.erase(10); // 按值删除 auto it = s.find(20); if (it != s.end()) { s.erase(it); // 按迭代器删除 } ``` #### **(5) 查找元素** ```cpp if (s.find(10) != s.end()) { std::cout << "10 exists in set\n"; } ``` #### **(6) 遍历 `std::set`** ```cpp for (const auto& elem : s) { std::cout << elem << " "; } // 或使用迭代器 for (auto it = s.begin(); it != s.end(); ++it) { std::cout << *it << " "; } ``` --- ### **2. 完整示例** ```cpp #include <iostream> #include <set> int main() { std::set<int> s = {5, 2, 8, 2, 1}; // 自动去重并排序为 {1, 2, 5, 8} // 插入元素 s.insert(3); // 删除元素 s.erase(2); // 查找元素 if (s.count(5) > 0) { std::cout << "5 exists in set\n"; } // 遍历 std::cout << "Set elements: "; for (int x : s) { std::cout << x << " "; } std::cout << "\n"; return 0; } ``` **输出**: ``` 5 exists in set Set elements: 1 3 5 8 ``` --- ### **3. 关键特性** 1. **唯一性**:`std::set` 自动去重,重复插入无效。 2. **有序性**:默认按升序排列,可通过比较函数(如 `std::greater`)调整。 3. **高效查找**:基于红黑树实现,查找、插入、删除的时间复杂度为 \(O(\log n)\)。 4. **不可直接修改元素**:若需修改,需先删除旧值再插入新值。 --- ### **4. 常见操作** | 操作 | 代码示例 | |---------------------|----------------------------------| | 插入元素 | `s.insert(10);` | | 删除元素(按值) | `s.erase(10);` | | 删除元素(按迭代器)| `auto it = s.find(10); s.erase(it);` | | 查找元素 | `if (s.find(10) != s.end()) {...}` | | 检查是否存在 | `s.count(10) > 0` | | 获取大小 | `s.size()` | | 清空集合 | `s.clear()` | --- ### **5. 自定义排序** ```cpp struct CustomCompare { bool operator()(const int& a, const int& b) const { return a > b; // 降序 } }; std::set<int, CustomCompare> s_custom; s_custom.insert({1, 2, 3}); // 存储为 {3, 2, 1} ``` --- ### **6. 适用场景** - 需要快速查找且元素唯一的场景(如黑名单、去重)。 - 需要有序遍历的场景(如排名系统)。 --- ### **7. 与 `std::unordered_set` 的区别** | 特性 | `std::set` | `std::unordered_set` | |--------------------|---------------------|----------------------| | 底层实现 | 红黑树 | 哈希表 | | 是否有序 | 是(默认升序) | 否 | | 查找复杂度 | \(O(\log n)\) | \(O(1)\) 平均 | | 是否需要自定义哈希 | 否 | 是(若键不是基本类型)| --- ### **8. 常见问题** #### **(1) 如何遍历 `std::set` 并修改元素?** 需先删除旧值再插入新值: ```cpp auto it = s.find(10); if (it != s.end()) { s.erase(it); s.insert(100); } ``` #### **(2) 如何合并两个 `std::set`?** ```cpp std::set<int> s1 = {1, 2, 3}; std::set<int> s2 = {3, 4, 5}; s1.insert(s2.begin(), s2.end()); // s1 = {1, 2, 3, 4, 5} ``` #### **(3) 如何获取 `std::set` 的最大值/最小值?** ```cpp if (!s.empty()) { auto min = *s.begin(); // 最小值 auto max = *s.rbegin(); // 最大值(反向迭代器) } ``` --- ### **总结** - `std::set` 适用于需要唯一、有序存储的场景。 - 插入、删除、查找操作高效(\(O(\log n)\))。 - 若无需有序性,可考虑 `std::unordered_set`(\(O(1)\) 平均查找)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值