1.Vector删除重复元素
源代码:https://github.com/AnkangH/CSDN/tree/master/STL
这里介绍分为三种方法,Unique,Set和Map方法。Unique方法要求先对输入数组进行排序,删除重复元之后会改变相对顺序,输出为有序序列;Set方法因此储存结构有序,因此结果也为有序序列;Map方法可不改变原数组的相对顺序。
不要尝试使用双指针遍历数组的方法。如果使用索引遍历,那么只能确定哪些项重复而不能删除,因为erase使用迭代器作为参数,否则只能将数组移动至数组末尾,使用pop_back()删除。对于每一个数组元素都要遍历数组该项之后的元素,时间复杂度至少是O(N*N)。并且要注意,因为删除一个重复项后,数组的大小变化了,因此索引需要对应修改。如果是迭代器,那么要注意,erase(itr)之后,itr被释放了。因此这种方法太繁琐,不推荐使用。
1.1Unique方法
itr unique(itr1,itr2);是unique函数的原形,itr1和itr2是迭代器std::itreator,指代首尾位置,[itr1,itr2)包含itr1不包含itr2,unique将输入数组中的重复元素放到数组的末尾,itr返回指向数组第一个重复元素的迭代器。所以对于模版类vector,可以使用来unique和erase来删除重复元素,但是注意,unique只比较相邻项,如果重复元素不相邻,则不会认为是重复元素。因此unique只能用于排序元素的重复处理。
arr.erase(unique(arr.begin(),arr.end()),arr.end());
{
sort(arr.begin(), arr.end());//先将输入序列排序
arr.erase(unique(arr.begin(), arr.end()), arr.end());//删除序列末尾的重复项
}
1.2 Set方法
将原输入序列全部放入Set中,利用Set的互异性,删除重复元。将Set中的元素全部取出即为删除重复元后的序列,因为Set有序,且无法获取Set中每个元素在原输入序列中的相对位置,因此输出序列是有序的。
set<int> auxSet;//辅助集合
for (auto p : arr)
auxSet.insert(p);//输入序列入辅助集合
arr.clear();//输入序列清空
for (auto p : auxSet)
arr.push_back(p);//输入序列出辅助集合
1.3 Map方法
利用一个哈希表储存当前项是否出现过,遍历原输入序列,查表,若未出现,放入表中并向后继续遍历,否则删除该元素。因为erase()需要使用迭代器作为参数,因此这里使用迭代器遍历原输入序列。注意erase()的特性,删除的迭代器被释放,返回原序列中删除项之后的迭代器。因此删除重复项时,给迭代器赋值erase()的返回值即可使遍历继续。
map<int, int> exist;//辅助哈希表
auto itr = arr.begin();//迭代器遍历起点
while (itr != arr.end())//遍历输入序列
{
if (exist.count(*itr) == 0)//表中无该项
{
exist[*itr]++;//入表
itr++;//迭代器指向下一个 遍历继续
}
else//表中有该项
{
itr = arr.erase(itr);//删除该项 迭代器指向下一项 遍历继续
}
1.4测试
void deleteDupVector(vector<int>& arr, method m)
{
if (m == setFunc)//使用Set<>
{
set<int> auxSet;
for (auto p : arr)
auxSet.insert(p);
arr.clear();
for (auto p : auxSet)
arr.push_back(p);
}
else if (m == uniqueFunc)//使用Unique()
{
sort(arr.begin(), arr.end());
arr.erase(unique(arr.begin(), arr.end()), arr.end());
}
else if (m == mapFunc)//使用Map<>
{
map<int, int> exist;
auto itr = arr.begin();
while (itr != arr.end())
{
if (exist.count(*itr) == 0)
{
exist[*itr]++;
itr++;
}
else
{
itr = arr.erase(itr);
}
}
}
else
cout<<"method illegal."<<endl;
}
#include<iostream> //for cout endl
#include<set> //for set<>
#include<vector> //for vector<>
#include<algorithm> //for sort()
#include<map> //for map<>
using namespace std;
enum method{setFunc,uniqueFunc,mapFunc};//定义方法的枚举类型
void deleteDupVector(vector<int>&arr, method m);//arr待处理序列 m处理方法
int main()
{
vector<int>arr{ 23,45,21,21,66,12,3,3,3,1,6,32,23 };
cout << "Original Vector:" << endl;
for (auto p : arr)
cout << p << " ";
cout << endl;
cout << "Delete dup via Set:" << endl;
deleteDupVector(arr, setFunc);
for (auto p : arr)
cout << p << " ";
cout << endl;
arr={ 23,45,21,21,66,12,3,3,3,1,6,32,23 };
cout << "Delete dup via Unique:" << endl;
deleteDupVector(arr, uniqueFunc);
for (auto p : arr)
cout << p << " ";
cout << endl;
arr = { 23,45,21,21,66,12,3,3,3,1,6,32,23 };
cout << "Delete dup via Map:" << endl;
deleteDupVector(arr,