必须先排序,因为std::unique仅移除相邻重复元素,如{1,2,2,3,2}处理后为{1,2,3,2,2};排序使重复值连续,再配合unique+erase才能真正去重。

std::unique 本身不直接为容器去重,它只把相邻重复元素压缩成一个,并返回新逻辑结尾的迭代器;所以必须先排序,再用 unique + erase 组合才能真正去重。
为什么必须先排序?
std::unique 只移除连续重复的元素(即紧挨着的相同值),比如 {1,2,2,3,2} 经 unique 后变成 {1,2,3,2,2}(前4个是“去重后”序列,但末尾的 2 仍残留)——它根本不管非相邻重复项。只有排序后(如变成 {1,2,2,2,3}),重复元素才连续,unique 才有效。
标准用法:sort + unique + erase
对 vector、deque 等支持随机访问的容器,常用三步组合:
- 调用
std::sort排序(默认升序,或传自定义比较器) - 调用
std::unique,传入 begin() 和 end(),它返回去重后新范围的尾迭代器 - 用
erase删除从该尾迭代器到原 end() 的冗余元素
示例:
立即学习“C++免费学习笔记(深入)”;
vectorsort(v.begin(), v.end()); // → {1,1,3,3,4,5,5}
auto last = unique(v.begin(), v.end()); // → {1,3,4,5,?, ?, ?},last 指向第5个位置
v.erase(last, v.end()); // 删除后面,v 变为 {1,3,4,5}
注意 unique 不改变容器大小
std::unique 是“就地重排”,它把唯一元素往前挪,但不会自动缩容。原容器长度不变,只是逻辑上有效部分变短了。若跳过 erase,后续遍历时会看到“脏数据”(原重复值被覆盖后的残留)。所以 unique 必须和 erase 配合使用才算完成去重。
其他容器适配要点
list 提供自己的 unique() 成员函数,无需排序也能去重(但它只删相邻重复项,效果等同于 std::unique,不是全量去重);若要 list 全量去重,仍需先 sort() 再调成员 unique()。set/multiset 本质已有序且无重复,无需此流程。










