1. 程式人生 > >去掉陣列中重複出現元素的演算法

去掉陣列中重複出現元素的演算法

一.問題描述 在實際程式設計中我們經常遇到“去掉重複數字”等類似的問題,也就是“Remove the duplicate”問題。例如在“建立某個統計樣本時,要去掉重複的元素”。下面將給出這類問題的解決思路。 二.解決思路 解決上述問題基本上有三種思路: 第一種使用map容器過濾掉重複元素(適用於整形資料、字串等) 第二種:利用陣列進行去重,首先對該組資料進行排序,然後從頭遍歷陣列,判斷當前位置的資料和下一個位置的資料是否重複,若不重複,新增下一位中的資料到過濾後的陣列中,並把比較的基準資料設定為剛加入的這個資料,然後繼續進行比較。若重複,則跳過該資料去比較後面的(也可以做字串的比較),需要使用兩個指標(一個基準指標,一個遊標指標);
第三種:是對第二種方法的改進,第二種方法需要開闢新的空間儲存過濾後的元素,此方法中不需要開闢空間,只需用陣列中沒有重複的元素把重複的元素覆蓋,過程如下:
(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.不開闢陣列空間去重的思想 在去重操作實施前要保證資料的有序性,然後通過兩個指標在原陣列上面進行剔除重複元素,最後擷取陣列,得到去重後的陣列;