在C++的标准库算法中,unique函数主要用于处理容器中相邻的重复元素,它并不会直接删除元素,而是将重复的元素移动到容器的末尾,并返回指向去重后最后一个有效元素之后位置的迭代器。结合vector容器的特性,我们可以通过unique函数配合erase方法实现完整的去重操作。

unique函数的基本特性
unique函数定义在<algorithm>头文件中,它的核心逻辑是遍历容器,将不重复的元素依次移动到容器前部,重复的元素被覆盖到后部。需要注意的是,unique只能处理相邻的重复元素,如果容器中的元素是无序的,需要先对容器进行排序,才能保证去重效果。
unique函数有两种常用重载形式:
- 第一种只接收两个迭代器参数,使用==运算符判断元素是否相等
- 第二种额外接收一个二元谓词参数,用于自定义元素的相等判断规则
vector去重的基本步骤
使用unique函数对vector去重的完整流程分为三步:排序、去重、删除末尾冗余元素。下面是具体的实现示例:
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
// 初始化一个包含重复元素的vector
std::vector<int> nums = {1, 3, 2, 3, 5, 2, 1, 4, 5};
// 第一步:对vector进行排序,让相同元素相邻
std::sort(nums.begin(), nums.end());
// 第二步:调用unique函数,返回去重后的尾后迭代器
auto new_end = std::unique(nums.begin(), nums.end());
// 第三步:删除末尾的冗余元素
nums.erase(new_end, nums.end());
// 输出去重后的结果
std::cout << "去重后的元素:";
for (int num : nums) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
上述代码的执行逻辑是:先通过sort将nums中的元素排序为{1,1,2,2,3,3,4,5,5},然后unique将不重复的元素移到前面,此时容器内容变为{1,2,3,4,5,3,4,5,5},返回的new_end指向第6个元素的位置,最后erase删除从new_end到末尾的所有元素,得到最终的去重结果。
自定义类型的去重实现
如果vector中存储的是自定义类型,需要自定义相等判断规则才能正确使用unique函数。下面的示例展示了自定义Person类型的去重操作:
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
// 自定义Person类型
struct Person {
std::string name;
int age;
};
// 自定义排序规则:先按name排序,name相同按age排序
bool cmp(const Person& a, const Person& b) {
if (a.name != b.name) {
return a.name < b.name;
}
return a.age < b.age;
}
// 自定义相等判断规则:name和age都相同则认为是重复元素
bool isSame(const Person& a, const Person& b) {
return a.name == b.name && a.age == b.age;
}
int main() {
std::vector<Person> persons = {
{"张三", 20},
{"李四", 25},
{"张三", 20},
{"王五", 30},
{"李四", 25}
};
// 先按自定义规则排序
std::sort(persons.begin(), persons.end(), cmp);
// 使用带自定义谓词的unique函数去重
auto new_end = std::unique(persons.begin(), persons.end(), isSame);
// 删除冗余元素
persons.erase(new_end, persons.end());
// 输出去重结果
std::cout << "去重后的人数:" << persons.size() << std::endl;
for (const auto& p : persons) {
std::cout << "姓名:" << p.name << ",年龄:" << p.age << std::endl;
}
return 0;
}
unique函数的注意事项
使用unique函数时需要注意以下几点:
- unique不会修改容器的大小,只是移动元素位置,必须配合erase才能实际删除重复元素
- 如果容器未排序,unique只能去除相邻的重复元素,无法处理分散的重复项
- unique的时间复杂度为O(n),排序的时间复杂度为O(nlogn),整体去重的时间复杂度由排序决定
- 对于已经有序的vector,可以直接调用unique和erase完成去重,不需要再次排序
不同去重场景的选择
如果不需要保留原vector的元素顺序,使用sort+unique+erase的方式效率最高;如果需要保留原顺序,可以使用额外的set或者unordered_set辅助去重,不过这种方式会额外占用空间。开发者可以根据实际的场景需求选择合适的去重方案。
uniquevector去重std_unique修改时间:2026-07-05 11:39:23