編程珠璣第一章補充

2、求出2.5億個整數中不重複的數字,注意內存無法存下2.5億的數字。

(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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章