删除数组中重复的值

本文介绍了一种高效去除数组中重复元素的方法,并通过比较不同算法的时间复杂度和空间复杂度,提供了多种实现方式,包括使用STL库、标志数组和符号标志法。这些方法适用于不同场景下的优化需求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <iostream>
#include <vector>
#include <algorithm>//STL算法支持


using namespace std;


int reduce(long a[],int n)//删除数组中重复的值并排序,返回数组缩减后数组中的元素数目
{
vector<long> v(a,a+n);
sort(v.begin(),v.end());//unique()是剔除数组重复的,可是他是剔除相邻之间字符重复的,所以要先排序
v.erase(unique(v.begin(), v.end()),v.end());//unique()剔除重复后数组长度还是没变,所以要手动去除剩下的不需要的长度

for(int i=0;i<v.size();i++)
a[i]=v[i];

return v.size();
}


void main()
{
long a[6]={1,2,3,1,2,4};
int n=reduce(a,6);
cout<<n<<endl;
for(int i=0;i<n;i++)
cout<<a[i]<<" ";
cout<<endl;


}


结果是这样


第一个是数组长度,第二行是数组内容




另外网上看到一个单纯去除数组中重复元素的

来源是http://blog.youkuaiyun.com/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");

        }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值