C++ STL 学习笔记(一):vector 去重的三种实现方法详解
.1 基础数据类型去重unique()函数作用是去掉容器中相邻元素的重复元素然后返回指向第一个重复元素的迭代器。unique()实质上是一个伪去除它并不是真正把重复的元素删除而是用不重复的元素把重复的元素覆盖了所以总长度其实是不变的。 因此在利用unique()函数前需要对容器内的数据排序可以通过sort()函数实现。sort()函数的作用是对容器指定范围内的元素按指定格式进行排序默认从小到大。在利用unique()函数后需要擦除从返回的迭代器对于的元素到最后元素的所有的元素可以通过erase()函数实现。erase()函数的作用是擦除容器指定范围内的元素。综上所属去除的主要思路先用sort排序让重复元素相邻、再唯一用unique把重复元素移到容器的末尾、最后用erase()于删除最后面的那段“重复”元素。对于 对于基础类型数据如int,float等最简单直接的方法是使用上述的sortuniqueerase组合。下面是代码案例实现#include iostream #include vector #include algorithm using namespace std; int main() { vectorint vec {1, 2, 3, 2, 1, 4, 5, 4}; cout 去重前: ; for (int num : vec) cout num ; cout endl; // 排序后去重 sort(vec.begin(), vec.end()); vec.erase(unique(vec.begin(), vec.end()), vec.end()); cout 去重后: ; for (int num : vec) cout num ; cout endl; return 0; }其中注意sort()函数的头文件#includealgorithmunique()函数的头文件#includeiostreamerase()函数的头文件#includevector1.2 自定义结构体去重 另外对于容器中如结构体、类对象等为了实现去重操作还可以通过对sort算法需要重载操作符或定义比较函数对unique算法需要重载操作符通过对其中的某一个成员变量进行操作来实现然后采用sortuniqueerase。其代码实现如下#include iostream #include vector #include algorithm using namespace std; struct Person { string name; int age; // 定义相等运算符 bool operator(const Person other) const { return name other.name age other.age; } }; // 定义比较函数 bool comparePerson(const Person a, const Person b) { if (a.name ! b.name) return a.name b.name; return a.age b.age; } int main() { vectorPerson people { {Alice, 25}, {Bob, 30}, {Alice, 25}, {Charlie, 35}, {Bob, 30} }; cout 去重前:\n; for (const auto p : people) cout p.name ( p.age )\n; sort(people.begin(), people.end(), comparePerson); people.erase(unique(people.begin(), people.end()), people.end()); cout \n去重后:\n; for (const auto p : people) cout p.name ( p.age )\n; return 0; }其中关键点必须定义operator用于unique判断相等代码简介但会改变原始顺序对于大型数据集合利用set的集合去重更高效1.3 使用set进行去重 对vector的去重操作还可以利用set容器的特性实现思路比较简单对于自定义类型可以使用set自动去重的特性需要定义operator运算符。其案例代码如下#include iostream #include vector #include set using namespace std; struct Product { string id; double price; // 定义小于运算符 bool operator(const Product other) const { if (id ! other.id) return id other.id; return price other.price; } }; int main() { vectorProduct products { {P1001, 99.99}, {P1002, 199.99}, {P1001, 99.99}, {P1003, 299.99}, {P1002, 199.99} }; cout 去重前:\n; for (const auto p : products) cout p.id ($ p.price )\n; // 使用set去重 setProduct uniqueProducts(products.begin(), products.end()); products.assign(uniqueProducts.begin(), uniqueProducts.end()); cout \n去重后:\n; for (const auto p : products) cout p.id ($ p.price )\n; return 0; }其关键点如下set基于operator自动排序和去重代码简洁但会改变原始顺序对于大型数据集set方法可能更高效方法比较方法适用场景时间复杂度代码复杂度sortunique基础数据类型O(n log n) O(n)低自定义结构体sortunique需要保持顺序的自定义类型O(n log n) O(n)中set去重不需要保持顺序的自定义类型O(n log n)低