目录
容器特性
C++ 中的 set 容器是一个以二叉搜索树(通常是红黑树)组织的容器,该容器中的每个元素都唯一,并自动按照特定的顺序(默认是升序)排列。
容器特性
- 唯一性:set 中的所有元素都是唯一的。
- 自动排序:元素插入后,会根据元素的值进行自动排序。
- 不支持直接的元素访问:不能像 std::vector 或 std::array 那样使用下标操作符 [] 直接访问元素。访问 set 中的元素需要通过迭代器。
- 效率:插入、删除和查找操作的时间复杂度为对数级别,即 O(log n)。
- 动态内存分配:由于其基于树的结构,set 在运行时可以动态增长或缩减。
使用场景
- 当需要维护一个不包含重复元素的集合时。
- 当元素的插入顺序不重要,但随时需要有序序列时。
- 当需要频繁地进行查找、插入和删除操作,并且要求这些操作有很好的性能时。
构造函数
默认构造函数
用途:无参数,初始化为空集合。
语法:std::set<Key, Compare, Allocator> set;
返回值:构造出的空 std::set 对象。
std::set<int> set1; // 空的集合
范围构造函数
用途:接受两个迭代器,将范围内的元素添加到集合中。
语法:std::set<Key, Compare, Allocator> set(InputIterator first, InputIterator last);
返回值:将指定范围的元素添加到集合中的 std::set 对象。
int arr[] = {1, 2, 3, 4, 5}; std::set<int> set2(arr, arr+5);
拷贝构造函数
用途:接受另一个同类型的 set 对象,创建一个复制的集合。
语法:std::set<Key, Compare, Allocator> set(const std::set& other);
返回值:一个与 other 集合相同的新集合。
std::set<int> set3(set2);
初始化列表构造函数
用途:接受一个初始化列表,创建一个含有所给元素的集合。
语法:std::set<Key, Compare, Allocator> set(std::initializer_listkey ilist);
返回值:一个含有 ilist 中所有元素的新集合。
std::set<int> set5 = {5, 4, 3, 2, 1};
大小函数
函数 size
用途:获取集合中元素的总数。
语法:size_type size() const noexcept;
返回值:容器中元素的个数,类型为 size_type。
std::set<int> set1 = {1, 2, 3, 4, 5}; std::cout << "Number of elements in set1: " << set1.size() << std::endl;
函数 empty
用途:检查 std::set 容器是否为空。
语法:bool empty() const noexcept;
返回值:如果集合为空返回 true,否则返回 false。
std::set<int> set2; std::cout << "Is set2 empty? " << (set2.empty() ? "Yes" : "No") << std::endl;
函数 max_size
用途:获取集合能够容纳的最大元素数量。
语法:size_type max_size() const noexcept;
返回值:集合可能包含的最大元素数量,类型为 size_type。
std::set<int> set3; std::cout << "Maximum number of elements in set3: " << set3.max_size() << std::endl;
增加删除
函数 insert
用途:向集合中增加新的唯一元素。
语法:pair<iterator, bool> insert(const value_type& value);
返回值:返回一个 pair,其中包含一个迭代器和一个布尔值。迭代器指向被插入的元素,布尔值表示元素是否成功插入(如果元素已存在,则不会插入,并且 bool 值为 false)。
std::set<int> myset; // 插入元素 auto result = myset.insert(1); std::cout << "Element 1 inserted: " << (result.second ? "Yes" : "No") << std::endl;
函数 emplace
- 用途:在集合中构造新元素,通常比 insert 更高效。
- 语法:pair<iterator,bool> emplace(Args&&... args);
- 返回值:与 insert 方法相同。
函数 erase
用途:删除集合中的元素。
语法:size_type erase(const value_type& value);
返回值:删除的元素数量(对于 std::set 来说要么是 0,要么是 1,因为集合中元素唯一)。
std::set<int> myset = {1, 2, 3, 4, 5}; // 删除元素 size_t num_erased = myset.erase(3); std::cout << "Number of elements erased: " << num_erased << std::endl;
函数 clear
用途:清空整个集合。
语法:void clear() noexcept;
返回值:无返回值。
std::set<int> myset = {1, 2, 3, 4, 5}; // 清空集合 myset.clear(); std::cout << "Set is empty: " << (myset.empty() ? "Yes" : "No") << std::endl;
重复元素
std::set
- 函数用途:std::set维护一组不重复的元素,每个元素值必须是唯一的。
- 语法:std::set<value_type> set_obj;
- 返回值:插入操作会返回一个pair,包含一个迭代器和一个布尔值,迭代器指向新元素或重复元素的位置,布尔值指示是否插入了新元素。
std::multiset
函数用途:允许元素值重复,同一个值可以出现多次。
语法:std::multiset<value_type> multiset_obj;
返回值:插入操作只返回一个指向插入元素的迭代器,因为std::multiset允许重复值。
#include <iostream> #include <set> int main() { // 使用std::set std::set<int> s; s.insert(1); s.insert(1); // 结果:只有一个元素1 for(auto &elem : s) { std::cout << elem << ' '; } // 使用std::multiset std::multiset<int> ms; ms.insert(1); ms.insert(1); // 结果:两个元素1 for(auto &elem : ms) { std::cout << elem << ' '; } return 0; }
查找统计
函数 find
- 用途:在集合中查找一个特定值的元素。
- 语法:iterator find(const value_type& value) const;
函数 count
- 用途:由于 std::set 中的元素是唯一的,count 函数用于检查元素是否存在于集合中。
- 语法:size_type count(const value_type& value) const;
代码
#include <iostream> #include <set> int main() { std::set<int> set1 = { 1,2,3,4,5 }; auto ret = set1.find(454); if (ret != set1.end()) { std::cout << "Find Success" << std::endl; } else { std::cout << "Find Failed" << std::endl; } auto ret1 = set1.count(1); std::cout << "Elm Number of -> " << ret1 << std::endl; std::multiset<int> set2 = { 1,1,1,1,1,1,2,233,44,534,5643,6 }; auto ret2 = set2.count(1); std::cout << "Elm Number of -> " << ret2 << std::endl; return 0; }
关联存储
Pair是C++标准模板库(STL)中的一种工具,它允许你将两个可能不同类型的值存储为一个单元。
一个pair通常用于将两个关联值组合在一起,比如在一个map容器中关联一个key和一个value。
#include <iostream> #include <set> int main() { //定义初始化 std::pair<std::string, int>obj("ANLIAN", 19); std::cout << obj.first << obj.second << std::endl; //成员赋值 模板中第一个为first 第二个为second obj.first = "0xCC"; obj.second = 18; std::cout << obj.first << obj.second << std::endl; //基于make_pair初始化 std::pair<std::string, int>Stu = std::make_pair("0xCC", 18); std::cout << Stu.first << Stu.second << std::endl; std::set<int>set1; auto ret = set1.insert(1); std::cout << typeid(ret.first).name() << std::endl; std::cout << typeid(ret.second).name() << std::endl; return 0; }