去除數組中的重復數字
Sailor_forever sailing_9806@163.com 轉載請注明
http://blog.csdn.net/sailor_8318/archive/2008/10/12/3060259.aspx
××××××××××××××××××××××××××××××××××
題目: 有一個數組t[100],存放了1~99之間的數字,用效率較高的代碼把重復數字去掉。例如數組{1,2,2,2,3,5,6,6}變成{1,2,3,5,6}。
××××××××××××××××××××××××××××××××××
申請標志數組
此題重復的數字可能不只一個,上述求和的方法不行了。因為是高效率,我們可以采用空間換時間的策略來解決。
設立訪問標志數字,初始化為0,訪問到N時將標志數字的第N個元素置為N
最后遍歷該數組,若標志數組中對應值為非0,則順序存儲該數字於原數組中,最后返回去除重復數字后的有效數的個數
int RemoveRep(int array[], int n)
{
int *arrayflag = (int *)malloc(n*sizeof(int));
int left = 0, i = 0;
while(i<n)
arrayflag[i++] = false; //初始化標志數組
for(i=0;i<n;i++)//剔除算法
{
arrayflag[array[i]] = array[i]; //將出現過的數保存到對應的位置
}
for(i=0;i<n;i++) //取出有效數
{
if(arrayflag[i] != false)
array[left++] = arrayflag[i];
}
return left;
}
××××××××××××××××××××××××××××××××××
符號標志法
上述方法的空間復雜度為O(N),利用符號位作為標志即可不申請O(N)標志數組
int SignedRemoveRep(int array[], int n)
{
int i,left = 0;
for(i=0;i<n;i++)//將出現過的位置置負號標志
{
if(array[i] > 0) //可以直接做下標
{
array[array[i]] = -array[array[i]];
}
else
{
if(array[-array[i]] > 0) //為正時才是第一次置標志
array[-array[i]] = -array[-array[i]];
}
}
for(i=0;i<n;i++)//抽取算法
{
if(array[i] < 0) //根據標志順序保存出現過的值
array[left++] = i;
}
return left;
}
××××××××××××××××××××××××××××××××××
void main(void)
{
int t[100];
int i,j,left;
for(i=0;i<100;i++) //隨機產生100個數字
{
j = rand()%99+1;
t[i] = j;
printf("%d ",t[i]);
if(i%10 == 9)
printf("/n");
}
//left = RemoveRep(t, 100);
left = SignedRemoveRep(t, 100);
for(i=0;i<left;i++)
{
printf("%d ",t[i]);
if(i%10 == 9)
printf("/n");
}
}