std::set详解与应用:生成不重复的字符,确保每个字符唯一
目录
1. 什么是 std::set?
2. 基本用法
a. 创建 set
b. 插入元素
c. 查看元素
d. 删除元素
e. 遍历 set
3. std::set 的特点
a. 自动排序
b. 唯一性
c. 时间复杂度
4. std::set 与 std::unordered_set 的区别
5. 总结
std::set
是 C++ 标准库中非常有用的一种容器,它提供了一个自动排序且不允许重复元素的集合。它通常用于需要存储一组元素并且需要确保每个元素唯一的场景。
1. 什么是 std::set
?
std::set
是 C++ 标准库中的一个关联容器。它的主要特点有:
-
自动排序:元素在
std::set
中是按特定顺序自动排序的(默认是升序)。你不需要手动排序,set
会在插入元素时自动完成排序。 -
唯一元素:
std::set
中的每个元素都是唯一的,重复的元素不会被插入。试图插入重复元素时,插入操作会失败。 -
快速查找:
std::set
是基于平衡二叉搜索树(通常是红黑树)实现的,因此它能在 O(log N) 时间内进行查找、插入和删除。
2. 基本用法
-
std::set
使用时,你需要包含头文件:#include <set>
a. 创建
set
你可以使用默认构造函数创建一个空的
set
:std::set<int> mySet; // 创建一个存储整数的空 set
你也可以初始化一个
set
,比如通过列表初始化:std::set<int> mySet = {5, 3, 8, 1};
b. 插入元素
使用
insert
方法来插入元素:mySet.insert(10); // 向 set 中插入 10 mySet.insert(3); // 3 已经存在,不会插入
如果元素已经存在,
insert
方法不会做任何操作,set
中的元素保持不变。c. 查看元素
你可以使用
find
来查看set
中是否包含某个元素:auto it = mySet.find(3); // 查找元素 3 if (it != mySet.end()) { std::cout << "Found: " << *it << std::endl; // 找到元素 } else { std::cout << "Not found" << std::endl; // 未找到元素 }
find
方法返回一个迭代器。如果元素存在,它返回指向该元素的迭代器;如果不存在,返回set.end()
。d. 删除元素
使用
erase
方法删除元素:mySet.erase(5); // 删除元素 5
如果你传入一个迭代器,也可以删除某个特定位置的元素:
auto it = mySet.find(3); if (it != mySet.end()) { mySet.erase(it); // 删除迭代器指向的元素 }
e. 遍历
set
std::set
是有序的,你可以通过迭代器来遍历它:for (auto it = mySet.begin(); it != mySet.end(); ++it) { std::cout << *it << " "; // 输出每个元素 } std::cout << std::endl;
你还可以使用范围-based for 循环:
for (const int& value : mySet) { std::cout << value << " "; // 输出每个元素 } std::cout << std::endl;
3.
std::set
的特点a. 自动排序
std::set
会根据元素的大小自动排序,默认情况下是按升序排列的。例如:std::set<int> mySet = {5, 3, 8, 1}; for (const int& value : mySet) { std::cout << value << " "; // 输出 1 3 5 8(自动排序) } std::cout << std::endl;
如果你希望使用自定义排序规则,可以提供一个比较函数:
std::set<int, std::greater<int>> mySet = {5, 3, 8, 1}; // 按降序排序 for (const int& value : mySet) { std::cout << value << " "; // 输出 8 5 3 1 } std::cout << std::endl;
b. 唯一性
std::set
中的元素是唯一的。插入重复元素时,set
会忽略重复的插入:std::set<int> mySet = {1, 2, 3}; mySet.insert(2); // 不会插入,因为 2 已经在 set 中 mySet.insert(4); // 会插入 4 for (const int& value : mySet) { std::cout << value << " "; // 输出 1 2 3 4 } std::cout << std::endl;
c. 时间复杂度
由于
std::set
是基于红黑树(平衡二叉搜索树)实现的,插入、删除和查找操作的时间复杂度都是 O(log N),其中 N 是set
中元素的个数。4.
std::set
与std::unordered_set
的区别std::set
和std::unordered_set
都是用于存储唯一元素的容器,但是它们有以下区别: -
排序:
std::set
会自动对元素进行排序,而std::unordered_set
不会,它是基于哈希表实现的,因此元素的顺序是不可预测的。 -
查找效率:
std::unordered_set
的查找效率一般比std::set
更高,尤其是当元素很多时。unordered_set
的查找时间复杂度通常是 O(1),但是在最坏情况下可能会退化为 O(N);而std::set
的查找时间复杂度始终是 O(log N)。 -
std::set
是一个基于平衡二叉搜索树的容器,具有自动排序和唯一性。 -
插入、删除和查找元素的时间复杂度都是 O(log N)。
-
它适用于需要存储有序数据且不允许重复元素的场景。
5. 总结
-
std::set
是一个基于平衡二叉搜索树的容器,具有自动排序和唯一性。 -
插入、删除和查找元素的时间复杂度都是 O(log N)。
-
它适用于需要存储有序数据且不允许重复元素的场景