unique是STL中一个比较实用而且非常常用的函数之一了;
作用就是容器或数组去重,但是并不是完全的去重;它只是把重复的元素放在了容器的后面,而且去重前一定要先排序;
头文件:#include<algorithm>
特点:
- 去重的是有序容器,所以如果无序的话需要先sort排序
- 去重后重复的数据并没有删除,只是移到了容器后面
- 返回迭代器,迭代器指向的是重复元素的首地址(可以借用这一点删除后面的重复元素)
下面就用一个案例来简单说明:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main() {
vector<int> vec = { 1, 4, 3, 1, 2, 3, 4, 1, 3, 2 }; // 包含重复数据的vector容器
sort(vec.begin(), vec.end()); // 对vec容器进行从小到大排序
unique(vec.begin(), vec.end()); // 对vec容器进行去重
for (auto i : vec) cout << i << " "; // 输出去重结果
cout << endl;
return 0;
}
输出结果:
1 2 3 4 2 3 3 3 4 4
可以看到从前四个数(下标到3)已经是去重的结果,后面(从下标4开始)都是重复的数据;
那么如何把后面删除达到真正的去重呢?
先看看unique的返回值:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main() {
vector<int> vec = { 1, 4, 3, 1, 2, 3, 4, 1, 3, 2 }; // 包含重复数据的vector容器
sort(vec.begin(), vec.end()); // 对vec容器进行从小到大排序
vector<int>::iterator it = unique(vec.begin(), vec.end()); // 接受unique的返回值
cout << "unique去重后的下标为:" << it - vec.begin() << endl; // 输出迭代器在容器中对应的下标
return 0;
}
输出结果:
unique去重后的下标为:4
可以看到unique返回的迭代器位置就在重复元素的首元素,下标为4的位置;
那么我们就可以借用这一点用erase函数删除重复元素了;
测试代码:
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int main() {
vector<int> vec = { 1, 4, 3, 1, 2, 3, 4, 1, 3, 2 }; // 包含重复数据的vector容器
sort(vec.begin(), vec.end()); // 对vec容器进行从小到大排序
vector<int>::iterator it = unique(vec.begin(), vec.end()); // 接受unique的返回值
vec.erase(it, vec.end()); // 删除最后重复元素
for (auto i : vec) cout << i << " "; // 输出删除后的结果
return 0;
}
输出结果:
1 2 3 4
可以看到所有的重复元素都已经删除了;
综上,当我们用unique想要真正删除重复元素时,我们只需要这两步(以vector为例):
vector<int> vec = { 1, 4, 3, 1, 2, 3, 4, 1, 3, 2 };
1.排序
sort(vec.begin(), vec.end());
2.删除
vec.erase(unique(vec.begin(), vec.end()), vec.end());