去除一个数组中的重复字符(100)

少数派007 2009-03-12 05:30:14
如int a[] = {1,1,2,5,1,6,2,8,3}

得到的结果是 1,2,5,6,8,3
不用考虑排序问题

int a[] = {1,1,1,1,5,1,2,3,4};
int temp = sizeof(a)/sizeof(int);

for(int i=1;i<temp;i++)
{
int j=0;
int flag=0;
while(j<i)
{
flag=0;
if(a[i]==a[j])
{
for(int m=i;m<temp-1;m++)
{
a[m] = a[m+1];
}
a[temp-1] = -1;

temp--;
j=0;
flag=1;
}
if(flag!=1)
j++;
}
}

大家有什么更优的算法吗?
...全文
541 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
zsf81 2009-03-19
  • 打赏
  • 举报
回复
最简单的就去做单一比较,去掉重的
rivulettornado 2009-03-14
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 hqin6 的回复:]
C/C++ code我觉得ls的都不符合要求,lz是要保持顺序的,也就是说序列要求是原封不动的!

比如:

int a[] = {1,1,2,5,1,6,2,8,3}

得到的结果是 1,2,5,6,8,3

而不是:1 2 3 5 6 8

所以,我觉得,如果a里的数字有范围(最大别太大),那么用位图能很快很好!

否则的话,就得考虑其他办法了,排序在这应该用不上吧!
[/Quote]
九楼的位图法得到的就是原来顺序的结果,不是排序的结果
hjzwl1018 2009-03-14
  • 打赏
  • 举报
回复
这里用到的位图法本身就是一种hash
meteormeng 2009-03-14
  • 打赏
  • 举报
回复
up
soulmachine 2009-03-13
  • 打赏
  • 举报
回复
位图法终结版,9楼的加强版,理论上内存是原来的 1/32。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/** 理论上要应付所有整数,需要的位图的位置个数为 2^32,每个位置即一个bit,那么2^32bit=2^29byte */
#define MAX 2^27 /* 一个整数是4 byte,2^27 个整数 = 2^29byte */

#define PRACTICAL_MAX 2^10 /* 2^29 byte = 512M,内存占用太大,这里只用 2^10,可以应付0~2^15以内的整数了 */

/**
* @brief 位图法去除一坨整数中的重复数字
* @author soulmachine@gmail.com
* @aouthor My blog: http://www.yanjiuyanjiu.com
* @param[in] int_array 整数数组
* @param[in] 数组中的整数个数
* @return 成功返回0,失败返回非0
* @note 一个整数在32位机器上占4个字节,32个 bit,可以表示 32 个位置,某个位置为1,表示已经出现过
* @remarks 无
*/
int unique(unsigned int *int_array, int count)
{
int i = 0;
int j = 0;
unsigned int *bit_map = (unsigned int*)malloc(PRACTICAL_MAX*sizeof(unsigned int)); /* 位图 */
unsigned int *temp = (unsigned int*)malloc(count*sizeof(unsigned int)); /* 存放去重后的 int_array */
if(NULL == bit_map)
{
return -1;
}
if(NULL == temp)
{
return -1;
}
memset(bit_map, 0, PRACTICAL_MAX*sizeof(unsigned int));
memset(temp, 0, count*sizeof(unsigned int));

for(i = 0; i < count;++i)
{
int row = int_array[i]/32;
int column = int_array[i] % 32;
if(0 == (bit_map[row] & (1 << column))) // 第一次出现,则拷贝到 temp 中
{
temp[j++] = int_array[i];
bit_map[row] |= 1 << column; // 将此位置标记为已出现
}
}
for(i = 0; i < j; i++)
{
printf("%d ", temp[i]);
}

printf("\n");

return 0;
}



int main(int argc, char *argv[])
{
unsigned int a[] = {1,1,1,1,5,1,2,3,4};
return unique(a, 9);
}


flameearth 2009-03-13
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 hairetz 的回复:]
写了个位图的。不需要排序,时间复杂度为O(n),靠空间换时间。

C/C++ code
#define MAX 10000

using namespace std;

void main()
{
int i,j=0;
int bit_map[MAX]={0};
int a[] = {1,1,1,1,5,1,2,3,4};
int b[10]={0};
for(i=0;i<( sizeof(a)/sizeof(int) );i++)
{
if(bit_map[a[i]]==0)
{
b[j++]=a[i];
bit_map[a[i]]=1;
}

[/Quote]

高效~~ 学习了~
bo.cui 2009-03-13
  • 打赏
  • 举报
回复
恩~~
空间时间都想要,那确实比较麻烦!

一个一个比较也行~ 浪费时间,但是不用排序~~
sunnystone614 2009-03-13
  • 打赏
  • 举报
回复
主要看自己要求,要空间还是要时间
qq675927952 2009-03-13
  • 打赏
  • 举报
回复
up LS
zhongyonghb 2009-03-13
  • 打赏
  • 举报
回复
位图吧,简单点
太乙 2009-03-13
  • 打赏
  • 举报
回复
我觉得ls的都不符合要求,lz是要保持顺序的,也就是说序列要求是原封不动的!

比如:

int a[] = {1,1,2,5,1,6,2,8,3}

得到的结果是 1,2,5,6,8,3

而不是:1 2 3 5 6 8

所以,我觉得,如果a里的数字有范围(最大别太大),那么用位图能很快很好!

否则的话,就得考虑其他办法了,排序在这应该用不上吧!
wudeshou82666 2009-03-13
  • 打赏
  • 举报
回复
up
  • 打赏
  • 举报
回复
讨论地好热烈啊,如果位图还想扩展的话,可以考虑hash。
neeestth 2009-03-13
  • 打赏
  • 举报
回复
位图
george5016 2009-03-13
  • 打赏
  • 举报
回复
用STL好咯
phil1984 2009-03-13
  • 打赏
  • 举报
回复
copy( a, unique( a, a + sizeof( a ) / sizeof a[0] ), ostream_iterator<int>( cout, " " ) );
xtting_8984313 2009-03-12
  • 打赏
  • 举报
回复
数据保证没有太大的情况下,使用位图。
如果不确定排序后去除。
再或者,采用类似插入排序的法则,只不过碰到重复的不不插入,这样如果重复数据多的话,或许效率会好于其他排序后删除的做法。
qq27508570 2009-03-12
  • 打赏
  • 举报
回复
不好意思,14楼删除的判断语句得只去掉n--,多去了几行。
qq27508570 2009-03-12
  • 打赏
  • 举报
回复
改13楼,n和k最后都表示无重复字符数,殊途同归,呵呵



#include <stdio.h>

main()
{
int a[] = {1,1,2,5,1,6,2,8,3};
int len = sizeof(a)/sizeof(int);
int i, j, k, n;
int flag;

k = 1;
n = len;
for (i=1; i <len; i++)
{
flag = 0;
for (j=0; j <k; j++)
{
if (a[i] == a[j])
{
flag = 1;
break;
}
}

if (1 == flag)
{
n--;
}
else
{

a[k] = a[i];
k++;
}
}

for (i=0; i <k; i++)
{
printf("a[%1d]: %1d\n", i, a[i]);
}

getch();
}
qq27508570 2009-03-12
  • 打赏
  • 举报
回复
改11楼

#include <stdio.h>

main()
{
int a[] = {1,1,2,5,1,6,2,8,3};
int len = sizeof(a)/sizeof(int);
int i, j, k, n;
int flag;

k = 1;
n = len;
for (i=1; i <len; i++)
{
flag = 0;
for (j=0; j <k; j++)
{
if (a[i] == a[j])
{
flag = 1;
break;
}
}

if (1 == flag)
{
n--;
}
else
{
a[k] = a[i];
k++;
}
}

for (i=0; i <n; i++)
{
printf("a[%1d]: %1d\n", i, a[i]);
}

getch();
}
加载更多回复(12)

69,322

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧