在 C++ 里,std::set
屬于標準庫容器的一種,其特性是按照特定順序存儲唯一的元素。下面為你詳細介紹它的常見使用方法:
?
1. 頭文件引入
要使用std::set
,需要在代碼中包含相應的頭文件:
#include <set>
?2. 集合的定義與初始化
// 定義一個存儲int類型的空集合,默認按升序排列
std::set<int> s1;// 用初始化列表來初始化集合
std::set<int> s2 = {1, 2, 3};// 借助比較函數,定義一個按降序排列的集合
std::set<int, std::greater<int>> s3 = {3, 1, 2}; // 結果為3, 2, 1// 通過已有集合來初始化新集合
std::set<int> s4(s2);
?3. 元素的添加操作
? ?可以使用insert()
方法向集合中添加元素:
std::set<int> s;
s.insert(10); // 集合現在包含元素10
s.insert(20); // 集合現在包含元素10和20
s.insert(10); // 由于元素10已存在,不會重復添加
4. 元素的查找操作
若要查找集合中是否存在某個元素,可使用find()
或count()
方法:
auto it = s.find(20); // 如果找到元素20,it指向該元素;否則it等于s.end()
if (it != s.end()) {std::cout << "找到了元素:" << *it << std::endl;
}bool exists = s.count(20); // 若元素20存在,返回1;否則返回0
5. 元素的刪除操作
可以使用erase()
方法刪除集合中的元素:
s.erase(20); // 刪除元素20
s.erase(s.find(10)); // 通過迭代器刪除元素10
s.clear(); // 清空集合中的所有元素
6. 集合的遍歷操作
集合支持使用迭代器、范圍 for 循環或者 C++20 引入的范圍庫來遍歷元素:
// 使用迭代器遍歷
for (auto it = s.begin(); it != s.end(); ++it) {std::cout << *it << " ";
}// 使用范圍for循環遍歷
for (const auto& element : s) {std::cout << element << " ";
}// 使用C++20的范圍庫(需要包含<ranges>頭文件)
for (auto element : s | std::views::reverse) {std::cout << element << " "; // 逆序輸出元素
}
7. 集合的大小與判空
可以通過以下方法了解集合的大小以及判斷集合是否為空:
size_t size = s.size(); // 獲取集合中元素的數量
bool empty = s.empty(); // 判斷集合是否為空
8. 其他實用方法
集合還提供了一些其他有用的方法:
auto lower = s.lower_bound(15); // 返回第一個大于或等于15的元素的迭代器
auto upper = s.upper_bound(15); // 返回第一個大于15的元素的迭代器// 交換兩個集合的內容
std::set<int> s5 = {4, 5};
s.swap(s5);
9. 自定義比較函數
對于自定義類型,需要定義比較函數:
struct Person {std::string name;int age;
};// 按照age升序排列
struct Compare {bool operator()(const Person& p1, const Person& p2) const {return p1.age < p2.age;}
};std::set<Person, Compare> people = {{"Alice", 25}, {"Bob", 20}};
10. 多重集合(允許重復元素)
如果需要存儲重復元素,可以使用std::multiset
:
std::multiset<int> ms;
ms.insert(10);
ms.insert(10); // 允許插入重復的10
典型應用場景
- 自動對元素進行排序。
- 高效地去重(時間復雜度為 O (log n))。
- 快速查找、插入和刪除元素(時間復雜度均為 O (log n))。
注意要點
- 集合中的元素是不可變的,若要修改元素,需先刪除該元素,再插入新元素。
- 集合會自動對元素進行排序,因此插入順序不會被保留。