std::unique不能直接对普通数组去重,它仅压缩连续重复元素并返回新逻辑结尾迭代器;必须先排序,再调用std::unique,最后手动截断冗余部分。
std::unique 不能直接对普通数组去重
std::unique 不是“删除重复值”的函数,它只把**连续重复元素压缩成一个**,并返回新逻辑结尾的迭代器。如果原数组没排序,std::unique 会保留所有非相邻重复项,比如 {1,2,1} 经 std::unique 后仍是 {1,2,1}(因为两个 1 不相邻)。
所以必须先排序,再用 std::unique,否则结果不可靠。
- 对
std::vector:先std::sort(v.begin(), v.end()),再auto it = std::unique(v.begin(), v.end()),最后v.erase(it, v.end()) - 对 C 风格数组(如
int arr[5]):用指针传入,auto it = std::unique(arr, arr + 5),再用it - arr得到有效长度 - 注意:
std::unique不改变容器大小,只是把冗余元素挪到末尾,需手动截断
std::unique 的返回值是“新尾迭代器”,不是新容器
常见错误是以为调用 std::unique 后数组/容器就自动变短了。实际它只重排元素,比如 int a[] = {1,1,2,2,3},执行 std::unique(a, a+5) 后,a 可能变成 {1,2,3,2,3},而返回值是指向第 4 个位置(即第一个冗余元素)的指针。
- 必须配合
erase(容器)或记录长度(数组)才能真正“移除” - 对
std::vector,推荐写法:v.erase(std::unique(v.begin(), v.end()), v.end()) - 对数组,不能删内存,只能用返回值算出不重复元素个数:
int len = std::unique(arr, arr + n) - arr
自定义比较时,std::unique 要求“等价关系”而非简单相等
传入的二元谓词(如 [](int a, int b){ return a == b; })必须满足等价性:若 a 和 b 等价、b 和 c 等价,则 a 和 c 也得等价。否则行为未定义。