2、求出2.5亿个整数中不重复的数字,注意内存无法存下2.5亿的数字。
(1)说明你的思路
(2)写出你的算法,可以用语言实现或者用伪代码表示
(1)说明你的思路
(2)写出你的算法,可以用语言实现或者用伪代码表示
个人提示:位图法
1、这里用到两个位图,先填充第一个位图a。当发现一个数字被填充过之后,则用这个数字填充b。很明显,b中记录的是重复出现过的数字。
2、当扫描完一次之后。再扫描b位图。只要出现在b位图中的数,就拿去清除a位图中的位。最后a中的数字保证是只出现一次的。
3、最后把a位图中记录的数输出。
值得注意的是:输出的数可能是负数,为了处理方便在处理时,统一转化成为无符号数,输出的时候,再转换成为负数则可。
你可以先把ms的值改小一些进行测试。由于算法针对的是2.1亿的数据量,所以常规的小数据是体现不出优势的。
当改小ms的值为100之后,你输入的值需要位于1~99之间。(如果不改MS的值,那么代码为正解)
#include <stdio.h>
#include <stdlib.h>
#define BITSPERWORD 32
#define SHIFT 5
#define MASK 0x1F
const unsigned long long ms = 4294967295;
int a[134217728];
int b[134217728];
void set(int *a, unsigned int i) { a[i>>SHIFT] |= (1<<(i & MASK)); }
void clr(int *b, unsigned int i) { a[i>>SHIFT] &= ~(1<<(i & MASK)); }
int test(int *a, unsigned int i){ return a[i>>SHIFT] & (1<<(i & MASK)); }
int main()
{
int n;
unsigned int x;
unsigned long long i;
while (scanf("%d", &n) != EOF){
x = n;
if (test(a, x) == 0) set(a, x);
else set(b, x);
}
for (i = 0; i < ms; ++i){
x = i;
if (test(b, x)) clr(a, x);
}
for (i = 0; i < ms; ++i){
x = i;
if (test(a, x)) printf("%d\n", (int)x);
}
return 0;
}