今天看源码时碰到以下这段代码,收获STL小技巧之利用unique快速删除重复元素;
auto UniLab = mLastFrame.vSemObjLabel; std::sort(UniLab.begin(), UniLab.end()); UniLab.erase(std::unique( UniLab.begin(), UniLab.end() ), UniLab.end() );unique函数
unique是一个非常使用的函数,所在的头文件为:
#include
其作用为:去除容器或者数组中相邻且相同的元素。
实际上,unique的做法为当相邻位置出现重复时用下一个元素填补当前的位置,其只修改了[begin, end]之间的数值,并返回一个迭代器result,使得[begin, result]之间没有相邻的相同元素,表现地好像被“删除”了一样。
可以看以下这段代码:
#include#include #include using namespace std; vector input {0, 1, 3, 3, 2, 2, 3, 5, 5, 6, 7, 7}; int main(){ for(int i: input) cout << i; cout << endl; auto output_itr = unique(input.begin(), input.end()); for(int i:input) cout << i; cout << endl; cout << "len: " << output_itr-input.begin() << endl; return 0; }
其结果为:
013322355677 013235675677 len: 8
从其功能描述和代码的运行结果可以知道unique有几个特点:
①其只对容器的值做修改,不会改变容器的size;
②其返回一个迭代器result,且保证[begin, result]之间没有相邻相同元素;
当我们只选择[begin, result]之间的数据时,就像我们对容器中的相邻元素做了“删除”一样;
两个版本:
其中第一个版本默认使用"=="作为相等判断,第二个版本的第三个参数可以指定比较函数;
template用于删除重复元素inline _ForwardIterator unique(_ForwardIterator __first, _ForwardIterator __last) template inline _ForwardIterator unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __binary_pred)
既然unique能够删除相邻的相同元素,那么只要先将容器进行排序,那么就有删除重复元素“==”删除相邻相同元素了;
对上面的代码稍加改动即可完成删除重复元素的目的:
#include#include #include using namespace std; vector input {0, 4, 3, 7, 5, 2, 3, 2, 5, 6, 3, 7, 4}; int main(){ for(int i: input) cout << i; cout << endl; sort(input.begin(), input.end()); auto output_itr = unique(input.begin(), input.end()); for(int i:input) cout << i; cout << endl; input.erase(output_itr, input.end()); for(int i: input) cout << i; cout << endl; return 0; }
其结果为:
0437523256374 0234567455677 0234567总结
sort函数+unique函数可以快速实现去除一个容器中相同元素的目的,在本文中容器存储的是简单的整形数据,当存储数据更复杂时只需:
①将sort函数的compare函数和unique的“==”函数传入即可,和我之前写过的文章类似;
②或者对存储的数据结构的“>”和“= =”做重载;



