- C++
C++ 排序+去重 零基础完整教程
- @ 2026-8-10 15:20:53
C++ 排序+去重 零基础完整教程
核心组合:
sort()排序 +unique()去重 +erase()删除重复残余元素 适用:数组、vector容器,竞赛GESP/CSP高频考点
原理简单讲
- sort:把容器从小到大排好序,unique只能去掉相邻重复元素,所以必须先排序
- unique:把重复元素挪到容器末尾,返回重复段的起始迭代器,不会真正删除,只是移动
- erase:根据unique返回的位置,真正删掉后面重复的部分
⚠️重点:不去排序直接调用unique,完全无效!
头文件必备
#include <iostream>
#include <vector>
#include <algorithm> // sort、unique都在这个头文件
using namespace std;
示例1:vector 完整排序去重(最常用,竞赛首选)
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
// 定义vector,有很多重复数字
vector<int> v = {5, 2, 8, 2, 5, 1, 8, 3, 1};
cout << "原始数据:";
for(int i = 0; i < v.size(); i++)
{
cout << v[i] << " ";
}
cout << endl;
// 第一步:排序 sort(起始迭代器,结束迭代器)
sort(v.begin(), v.end());
cout << "排序之后:";
for(int i = 0; i < v.size(); i++)
{
cout << v[i] << " ";
}
cout << endl;
// 第二步:unique,将重复元素移到后面,返回重复元素第一个位置
auto pos = unique(v.begin(), v.end());
// 第三步erase:删除pos到末尾所有重复垃圾数据
v.erase(pos, v.end());
cout << "排序去重完成:";
for(int i = 0; i < v.size(); i++)
{
cout << v[i] << " ";
}
cout << endl;
return 0;
}
运行输出
原始数据:5 2 8 2 5 1 8 3 1
排序之后:1 2 2 3 5 5 8 8
排序去重完成:1 2 3 5 8
逐行解释关键语句
sort(v.begin(),v.end())
v.begin():容器第一个元素的位置v.end():容器最后一个元素下一个位置- 默认从小到大升序;想要降序:
sort(v.begin(),v.end(),greater<int>());
auto pos = unique(v.begin(),v.end());auto自动识别迭代器类型,pos保存重复段开头位置。
unique不会改变容器大小,只是把不重复元素往前覆盖。
v.erase(pos, v.end());从pos这个位置,一直删到末尾,真正删掉重复的残余。
示例2:普通数组排序去重(静态数组)
数组没有erase,unique返回指针,返回值是去重后有效数据的下一位指针,我们用这个指针计算新长度。
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int a[100] = {5,2,8,2,5,1,8,3,1};
int n = 9; // 当前数组有效元素个数
sort(a, a+n); //数组sort:首地址,首地址+有效个数
// unique返回去重后末尾的指针
int *p = unique(a, a+n);
//计算去重之后新的元素数量
int new_len = p - a;
cout << "数组去重后:";
for(int i=0; i<new_len; i++)
{
cout << a[i] << " ";
}
return 0;
}
输出:1 2 3 5 8
数组本身内存不会缩小,只用
new_len当做有效长度访问。
示例3:输入若干数字,排序去重(GESP真题风格完整代码)
输入:第一行n,第二行n个整数,输出去重升序结果
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
vector<int> arr(n);
for(int i = 0; i < n; i++)
{
cin >> arr[i];
}
sort(arr.begin(), arr.end());
auto last = unique(arr.begin(), arr.end());
arr.erase(last, arr.end());
//输出结果
for(int i = 0; i < arr.size(); i++)
{
if(i>0) cout << " ";
cout << arr[i];
}
cout << endl;
return 0;
}
输入:
9
5 2 8 2 5 1 8 3 1
输出:
1 2 3 5 8
常见坑点(考试必看)
- ❌不排序直接unique:完全无效!重复的元素不挨在一起,unique识别不出。
//错误写法
unique(v.begin(),v.end());
v.erase(...)
- ❌erase参数写错:
erase(v.end(), pos)顺序颠倒,程序直接崩溃。
永远:
erase(起点,终点),起点在前,终点在后。
- ❌数组忘记传入有效长度:
sort(a,a+100)会把数组后面大量0参与排序。 - ❌unique之后还继续使用原来size(),vector大小还没变小,要erase之后size才更新。
常用变体
1.降序排序再去重
sort(v.begin(),v.end(),greater<int>());
auto pos = unique(v.begin(),v.end());
v.erase(pos,v.end());
2.字符串排序去重
string s = "abacaba";
sort(s.begin(),s.end());
auto p = unique(s.begin(),s.end());
s.erase(p,s.end());
cout << s; //abc
速记模板(考试直接默写vector版本)
sort(v.begin(), v.end());
auto it = unique(v.begin(), v.end());
v.erase(it, v.end());
0 条评论
目前还没有评论...