//題目:在2.5億個整數中找出不重複的整數,記憶體不足以容納這2.5億個整數。 #include<stdio.h> #include<memory.h> /*每個數分配2bit,00表示不存在,01表示出現一次,10表示多次,11無意義用char數組儲存2-Bitmap,不用考慮大小端記憶體的問題映射關係如下:|00 00 00 00| //映射|3 2 1 0||00 00 00 00| //映射|7 6 5 4|……|00 00 00 00|*/unsigned char flags[1000]; //數組大小自訂,存放各個整數出現的次數1000*4=4000個整數 unsigned get_val(int idx) { int i = idx/4; //確定數組位置 int j = idx%4; //確定8bit內位置 unsigned ret = (flags[i]&(0x3<<(2*j)))>>(2*j); //0x3十六進位表示00 00 00 11可控制某個整數,擷取某個整數的出現次數 return ret; } /*已經過位元運算測試*/unsigned set_val(int idx, unsigned int val) { int i = idx/4; int j = idx%4; unsigned tmp = (flags[i]&~((0x3<<(2*j))&0xff)) | (((val%4)<<(2*j))&0xff); //或運算,前面保留其他位不變,後邊重設所需修改的位 flags[i] = tmp; return 0; } unsigned add_one(int idx) { if (get_val(idx)>=2) { return 1; } else { set_val(idx, get_val(idx)+1); return 0; } } //只測試非負數的情況; //假如考慮負數的話,需增加一個2-Bitmap數組. int a[]={1, 3, 5, 7, 9, 1, 3, 5, 7, 1, 3, 5,1, 3, 1,10,2,4,6,8,0}; int main() { int i; memset(flags, 0, sizeof(flags)); printf("原數組為:"); for(i=0;i < sizeof(a)/sizeof(int); ++i) { printf("%d ", a[i]); add_one(a[i]); } printf("\r\n"); printf("只出現過一次的數:"); for(i=0;i < 100; ++i) { if(get_val(i) == 1) printf("%d ", i); } printf("\r\n"); return 0; } 除了用2-Bitmap來計數標記以外,也可以用兩個1-Bitmap來實現(如果考慮正負數的情況,就四個1-Bitmap)
轉自:互連網