1 std::set 的主要应用场景
std::set 的主要应用场景包括那些需要存储唯一元素并且保持元素有序的情况。以下是一些具体的应用场景示例:
(1)去重操作: 当需要从一组数据中去除重复的元素时,std::set 是一个理想的选择。由于其内部实现的唯一性约束,任何尝试插入重复元素的操作都会被自动忽略。
(2)有序存储: std::set 中的元素默认按照升序排列,这使得它非常适合用于需要保持元素顺序的场景。比如需要存储一个用户的分数列表,并按照分数从低到高进行排序。
(3)快速查找: 由于 std::set 是基于红黑树实现的,它提供了快速的查找操作,平均时间复杂度为 O(log n)。这使得它非常适合用于需要频繁查找元素的场景。
(4)不允许重复键的映射: 在某些情况下,开发人员可能需要一个映射关系,其中键是唯一的,并且希望这些键能够自动排序。虽然 std::map 也提供了类似的功能,但如果只关心键的集合而不关心与键关联的值,那么 std::set 可能是一个更简洁的选择。
1.1 std::set 应用于去重操作
std::set 应用于去重操作的示例非常简单直接。由于 std::set 容器本身保证了元素的唯一性,所以当向 std::set 中插入数据时,任何重复的元素都会被自动忽略。以下是一个简单的示例,展示了如何使用 std::set 对一个包含重复元素的向量进行去重操作:
#include <iostream>
#include <vector>
#include <set>
int main()
{
// 原始向量,包含重复元素
std::vector<int> numbers = {
1, 2, 2, 3, 5, 5, 5, 4, 4 };
// 创建一个 set 容器来存储去重后的元素
std::set<int> unique_numbers(numbers.begin(), numbers.end());
// 输出去重后的元素
for (const auto& num : unique_numbers) {
std::cout << num << ' ';
}
std::cout << std::endl;
return 0;
}
上面代码的输出为:
1 2 3 4 5
在这个例子中,首先创建了一个包含重复元素的 std::vector。然后使用 std::set 的构造函数,通过传递向量的起始和结束迭代器,将向量的所有元素插入到 set 中。由于 set 的唯一性特性,重复的元素在插入时会被忽略。
最后使用范围基于的 for 循环遍历 set 中的元素,并将它们打印出来。输出将是去重后的元素列表,即 1 2 3 4 5。
注意:如果想保留原始向量的顺序,并且只想去除连续的重复元素,那么 std::set 可能不是最佳选择,因为它会对元素进行排序。在这种情况下,可以使用 std::unique 算法配合 std::erase 来达到目的:
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
// 原始向量,包含重复元素
std::vector<int> numbers = {
1, 2, 2, 3, 5, 5, 5, 4, 4 };
// 使用 std::unique 去除连续重复元素
auto it = std::unique(numbers.begin(), numbers.end());
// 擦除重复元素之后的部分
numbers.erase(it, numbers.end());
// 输出去重后的元素
for (const auto& num : numbers) {
std::cout << num << ' ';
}
std::cout << std::endl;
return 0;
}
上面代码的输出为:
1 2 3 5 4
这个示例中,std::unique 算法会重新排列容器中的元素,使得每个重复序列只保留第一个元素,并返回一个迭代器指向去重后序列的末尾。然后使用 std::vector::erase 成员函数删除这个迭代器之后的所有元素,从而得到最终的去重结果。这种方法保留了原始向量中元素的相对顺序,但仅去除了连续的重复元素。
1.2 std::set 应用于有序存储
std::set 存储的元素是唯一的,并且默认按照升序排列。这种有序存储的特性使得 std::set 在需要保持元素顺序的场景中非常有用。以下是一个简单的示例,展示了如何使用 std::set 来实现有序存储:
#include <iostream>
#include <set>
int main()
{
// 创建一个空的 set 容器
std::set<int> ordered_set;
// 向 set 中插入元素
ordered_set.insert(3);
ordered_set.insert(1);
ordered_set.insert(4);
ordered_set