std::unique仅移除相邻重复元素,不自动排序或缩容,必须先std::sort再用它,返回新末尾迭代器,需手动计算有效长度或配合vector::erase实现真正去重。

用 std::unique 去重 int 数组,必须先排序,否则只删相邻重复项 —— 这是最常踩的坑。
为什么 std::unique 不直接去重?
std::unique 不是“去重函数”,而是“移除相邻重复元素”的算法。它只比较连续位置的值,不关心整个数组是否有序。
常见错误现象:int a[] = {3,1,2,1,3}; std::unique(a, a+5) 返回迭代器指向第 4 个位置,但数组变成 {3,1,2,3,3},末尾的 3 是脏数据,且原数组长度没变。
- 必须配合
std::sort使用才能实现真正去重 - 它不改变容器大小,只是把唯一元素挪到前面,返回新逻辑结尾的迭代器
- 对原始数组操作后,需手动截断或用
vector配合erase
std::unique 在 int 数组上的标准写法
裸数组(int[])不能自动缩容,所以重点在“怎么拿到去重后的有效长度”和“怎么避免越界访问”。
立即学习“C++免费学习笔记(深入)”;
示例:
int arr[] = {1, 2, 2, 3, 3, 3, 4};
int n = 7;
std::sort(arr, arr + n);
auto new_end = std::unique(arr, arr + n);
int unique_n = new_end - arr; // 真实去重后长度-
new_end是指向新序列末尾后一位置的指针,不是元素个数 -
unique_n才是你该当数组长度用的值,后续遍历只能到arr[unique_n - 1] - 别直接用
std::unique后就以为数组变短了 —— 内存里后面还是旧值
用 vector 更安全的替代方案
裸数组容易误读长度、难管理内存;std::vector 配合 erase 能一步到位“真删掉”重复项。
示例:
std::vector<int> v = {5, 1, 5, 2, 1};
std::sort(v.begin(), v.end());
v.erase(std::unique(v.begin(), v.end()), v.end());-
v.size()此时就是去重后真实长度,无额外状态要维护 - 如果原数据顺序必须保留(比如按首次出现顺序去重),
std::unique就完全不适用,得手写哈希表或用std::set辅助记录 - 性能上:排序是 O(n log n),
unique是 O(n),整体瓶颈在排序
记住:std::unique 的作用域非常窄 —— 它只解决“相邻去重”这一件事。想靠它一步到位处理乱序 int 数组,不排序就是白忙活,还可能读到未定义值。










