69,322
社区成员
发帖
与我相关
我的任务
分享
#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);
}
我觉得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里的数字有范围(最大别太大),那么用位图能很快很好!
否则的话,就得考虑其他办法了,排序在这应该用不上吧!