去掉陣列中重複出現元素的演算法
阿新 • • 發佈:2019-01-06
一.問題描述
在實際程式設計中我們經常遇到“去掉重複數字”等類似的問題,也就是“Remove the duplicate”問題。例如在“建立某個統計樣本時,要去掉重複的元素”。下面將給出這類問題的解決思路。
二.解決思路
解決上述問題基本上有三種思路:
第一種:使用map容器過濾掉重複元素(適用於整形資料、字串等);
第二種:利用陣列進行去重,首先對該組資料進行排序,然後從頭遍歷陣列,判斷當前位置的資料和下一個位置的資料是否重複,若不重複,新增下一位中的資料到過濾後的陣列中,並把比較的基準資料設定為剛加入的這個資料,然後繼續進行比較。若重複,則跳過該資料去比較後面的(也可以做字串的比較),需要使用兩個指標(一個基準指標,一個遊標指標);
第三種:是對第二種方法的改進,第二種方法需要開闢新的空間儲存過濾後的元素,此方法中不需要開闢空間,只需用陣列中沒有重複的元素把重複的元素覆蓋,過程如下:
(1)基準指標首先指向陣列第0個位置,遊標指標指向第1個位置,比較兩指標所指向的資料是否相等,若相等,遊標指標向後移一位,基準指標不動,再次比較;若不相等,遊標指標所指向的資料複製到基準指標的下一位,基準指標和遊標指標各自從當前位置向後移一位,再次比較; (2)終止條件:遊標指標超過陣列的最後一位; (3)當前基準指標之前的一段陣列則為去重後的陣列(包括基準指標所指向的元素); 三.程式碼實現 1.map容器去重實現程式碼
2.開闢陣列空間去重實現程式碼 和第三種方法類似,在此不在贅述; 3.不開闢陣列空間去重程式碼
(1)基準指標首先指向陣列第0個位置,遊標指標指向第1個位置,比較兩指標所指向的資料是否相等,若相等,遊標指標向後移一位,基準指標不動,再次比較;若不相等,遊標指標所指向的資料複製到基準指標的下一位,基準指標和遊標指標各自從當前位置向後移一位,再次比較; (2)終止條件:遊標指標超過陣列的最後一位; (3)當前基準指標之前的一段陣列則為去重後的陣列(包括基準指標所指向的元素); 三.程式碼實現 1.map容器去重實現程式碼
#include<iostream> #include<map> void inserttomap(int *a, int n,std::map<int, int> &outmap); void sprintmap(std::map<int, int> &coutmap); void main() { int a[10] = { 1, 1, 2, 3, 4, 4, 5, 6, 6, 8 }; std::map<int, int> resultmap; inserttomap(a, 10, resultmap); sprintmap(resultmap); system("pause"); } void inserttomap(int *a, int n, std::map<int, int> &outmap) { std::map<int, int> testmap; std::pair< std::map< int, int >::iterator, bool > ret; for (int i = 0; i < n; i++) { ret = testmap.insert({ a[i], 1 }); if (!ret.second) { ++testmap[a[i]]; } } outmap = testmap; } void sprintmap(std::map<int, int> &coutmap) { auto map_it = coutmap.cbegin(); while (map_it!=coutmap.cend()) { std::cout << "元素" << map_it->first << "出現的次數為" << map_it->second <<std::endl; ++map_it; } }
2.開闢陣列空間去重實現程式碼 和第三種方法類似,在此不在贅述; 3.不開闢陣列空間去重程式碼
#include<iostream>
#include <algorithm>
void removemultip(int *a, int n, int &cout);
void main()
{
int a[10] = { 1, 1, 2, 3, 4, 4, 5, 6, 6, 8 };
std::sort(&a[0], &a[9]+1);//陣列排序
int scount;//過濾後陣列的有效位長度
removemultip(a, 10, scount);
for (int i = 0; i <= scount; i++)
{
std::cout << a[i] << std::endl;
}
system("pause");
}
void removemultip(int *a, int n,int &cout)
{
if (n <= 1)return;
int start = 0;//基準位置
int end = 1; //遊標位置
while (end<n)
{
if (a[start] == a[end])
{
++end;
}
else
{
a[start + 1] = a[end];
++start;
++end;
}
}
cout = start;
}
四.思想總結
1.map容器去重的思想
藉助map容器中不能插入重複key值的特性進行常數或者字串陣列去重,又藉助map.insert函式的返回值的標識可以統計重複元素出現的個數(在統計一組資料中出現次數最多的元素非常有用);
2.不開闢陣列空間去重的思想
在去重操作實施前要保證資料的有序性,然後通過兩個指標在原陣列上面進行剔除重複元素,最後擷取陣列,得到去重後的陣列;