C++ STL容器去重主要有两种方法:一是结合std::sort与std::unique,适用于vector等支持随机访问的容器,先排序使重复元素相邻,再用std::unique将重复元素移至末尾并配合erase删除;二是利用std::set或std::unordered_set的唯一性插入特性实现去重。前者原地操作、内存开销小,时间复杂度O(N log N);后者需额外O(N)空间,但代码简洁,其中unordered_set平均时间复杂度为O(N)。std::unique不直接改变容器大小,仅返回新逻辑末尾迭代器,需调用erase完成实际删除,体现STL算法与容器分离的设计思想。不同容器策略不同:vector/deque推荐sort+unique;list应使用其成员函数sort()和unique();set/map类容器键天然唯一,无需额外去重。选择方法时需权衡时间与空间复杂度、元素类型约束、是否保持顺序及原地修改需求,根据具体场景灵活选用。

在C++的STL中,实现容器的去重操作,主要有两大类方法:一种是利用
std::sort
std::unique
std::set
std::unordered_set
要实现C++ STL容器的去重,最常用且高效的方案,尤其对于
std::vector
std::deque
std::sort
std::unique
std::sort
std::unique
具体步骤是这样的:
std::sort(vec.begin(), vec.end());
std::unique
std::unique
erase
std::unique
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
#include <iostream>
#include <vector>
#include <algorithm> // for std::sort and std::unique
#include <set> // for std::set based de-duplication
#include <unordered_set> // for std::unordered_set based de-duplication
// 示例1: 使用 std::sort + std::unique 去重 std::vector
void deduplicate_vector_sort_unique(std::vector<int>& vec) {
std::cout << "Original vector (sort+unique): ";
for (int x : vec) std::cout << x << " ";
std::cout << std::endl;
std::sort(vec.begin(), vec.end());
// std::unique 返回一个迭代器,指向新的逻辑末尾
// 实际的删除操作需要结合 erase
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
std::cout << "Deduplicated vector (sort+unique): ";
for (int x : vec) std::cout << x << " ";
std::cout << std::endl;
}
// 示例2: 使用 std::set 去重 std::vector
void deduplicate_vector_set(std::vector<int>& vec) {
std::cout << "Original vector (set): ";
for (int x : vec) std::cout << x << " ";
std::cout << std::endl;
// 将vector元素插入到set中,set会自动处理唯一性
std::set<int> unique_elements(vec.begin(), vec.end());
// 清空原vector,再将set中的元素复制回来
vec.assign(unique_elements.begin(), unique_elements.end());
std::cout << "Deduplicated vector (set): ";
for (int x : vec) std::cout << x << " ";
std::cout << std::endl;
}
// 示例3: 使用 std::unordered_set 去重 std::vector
void deduplicate_vector_unordered_set(std::vector<int>& vec) {
std::cout << "Original vector (unordered_set): ";
for (int x : vec) std::cout << x << " ";
std::cout << std::endl;
// 将vector元素插入到unordered_set中
std::unordered_set<int> unique_elements(vec.begin(), vec.end());
// 清空原vector,再将unordered_set中的元素复制回来
vec.assign(unique_elements.begin(), unique_elements.end());
std::cout << "Deduplicated vector (unordered_set): ";
for (int x : vec) std::cout << x << " ";
std::cout << std::endl;
}
int main() {
std::vector<int> data1 = {1, 3, 2, 4, 3, 1, 5, 2, 6, 4};
deduplicate_vector_sort_unique(data1);
std::cout << "--------------------" << std::endl;
std::vector<int> data2 = {10, 30, 20, 40, 30, 10, 50, 20, 60, 40};
deduplicate_vector_set(data2);
std::cout << "--------------------" << std::endl;
std::vector<int> data3 = {100, 300, 200, 400, 300, 100, 500, 200, 600, 400};
deduplicate_vector_unordered_set(data3);
std::cout << "--------------------" << std::endl;
return 0;
}可以看到,
std::sort
std::unique
std::set
std::unordered_set
立即学习“C++免费学习笔记(深入)”;
std::unique
这确实是一个初学者常常会感到困惑的地方,我当初学习的时候也曾掉入这个“坑”。很多人会误以为
std::unique
std::unique
它的设计哲学,我认为体现了STL中算法与容器分离的原则。
std::unique
举个例子,如果你的
vector
{1, 2, 2, 3, 3, 3, 4}std::unique
{1, 2, 3, 4, 3, 3, 4}std::unique
4
vec.erase(unique_it, vec.end())
这种设计的好处在于,
std::unique
vector
去重策略的选择,很大程度上取决于你正在使用的具体STL容器类型,因为不同容器的底层实现和迭代器特性差异巨大。
std::vector
std::deque
std::sort
std::unique
erase
std::sort
std::set
std::unordered_set
std::set
std::unordered_set
std::list
std::list
std::sort
std::sort
std::list
sort()
unique()
list::sort()
list::unique()
std::list
myList.sort(); myList.unique();
std::vector
vector
std::list
std::set
std::unordered_set
list
std::set
std::unordered_set
std::set
std::multiset
std::map
std::multimap
std::unordered_set
std::unordered_map
std::set
std::unordered_set
std::map
std::unordered_map
map
std::map
std::multimap
std::vector
std::list
总的来说,理解容器的底层特性是选择去重策略的关键。对于顺序容器(
vector
deque
sort
unique
list
在实际项目中,选择去重方法并非一刀切,它涉及多方面的权衡考量,这往往也是体现一个开发者经验和对C++理解深度的点。
时间复杂度:
std::sort
std::unique
std::unique
std::set
std::set
std::unordered_set
std::unordered_set
std::list::sort()
std::list::unique()
list::sort()
list::unique()
空间复杂度:
std::sort
std::unique
std::vector
std::deque
std::sort
std::set
std::unordered_set
元素类型要求:
std::sort
operator<
std::unique
operator==
std::set
operator<
std::unordered_set
operator==
std::hash
unordered_set
是否需要保持原始顺序?
std::sort
std::unique
std::set
std::unordered_set
std::unordered_set
原地修改 vs. 创建新容器:
std::sort
std::unique
std::set
std::unordered_set
我的个人看法和经验是:
std::vector
std::deque
std::sort
std::unique
std::unordered_set
std::set
unordered_set
sort
unique
最终的选择,是性能、内存、代码可读性、以及对原始数据顺序要求的综合平衡。没有绝对“最好”的方法,只有最适合你当前需求的方法。
以上就是C++如何在STL中实现容器去重操作的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号