bitmap是一種簡單的資料結構,但在儲存空間壓縮方面卻使用廣泛。
bitmap就是用乙個bit位來標記某個元素是否存在:1表示存在,0表示不存在;而2-bitmap就是用兩個bit為來標記某個元素出現的次數:00出現0次,01出現1次,10出現2次及其以上,11無意義。
2-bitmap在記憶體中的表示如下:
[0] [1] [2] ……
|00 00 00 00|00 00 00 00|00 00 00 00| ……
3 2 1 0 7 6 5 4 11 10 9 8 ……
任何乙個可採用陣列作為輔助標記來解決的問題都可以用bitmap來解決,因為用陣列的每乙個元素作為標記的話,用bit同樣可以作為標記。當資料量比較小時,有時候為了操作方便,可直接採用陣列。但當資料量很大的時候,因為記憶體大小的原因或題目限定了可用記憶體大小,陣列就再沒法解決我們的問題, 而此時bitmap就顯示出其空間壓縮的威力了:如果用char型的陣列,標記同樣範圍內的數bitmap最多可以節省8倍空間,2-bitmap可節省4倍空間。若採用int型的陣列,bitmap和2-bitmap可以分別最多節省32倍、16倍的空間。
bitmap能用來處理以下問題:
(1)、字串方面
1、c語言str系列庫函式之strtok()、strspn()、strcspn()和strpbrk()函式都用到了bitmap。詳見c語言str系列庫函式之strtok()
、c語言str系列庫函式之strspn()、strcspn()和strpbrk()
;2、判斷乙個字串b中的字元是否都在另乙個字串a中出現(網上能搜到)。跟上面第1條博文鏈結裡的十分類似。
3、在乙個字串中找到第乙個只出現一次的字元(google面試題、網上能搜到)。
可以用26維的陣列統計26個字母出現的次數,然後順序查詢統計表直到查到到結果為1的就是要查到的字元。
也可以採用2-bitmap,更節省空間。
(2)、大資料
1、在2.5億個整數找出不重複的整數,記憶體不足以容納著2.5億個整數
對於問題1,整數可能是正數也可能是負數,首先只考慮正整數情況,採用2bitmap方法,用00表示不存在,01表示出現1次,10表示出現2次及以上,此方法總共需要的記憶體2^31*2bit = 1gb = 128mb(32位的正整數有2^31個,每個儲存需要2bit,所以就是1gb,換成位元組就是128mb),這樣記憶體就應該能夠容納了,最後在處理完所有的數後,只要輸出對應位為01的數即可。如果這2.5億個數裡面既有正數又有負數那麼就用兩個2bitmap分別儲存正數和負數(取絕對值儲存),零就隨便放,這是所需要的記憶體是256mb。
對於問題2,直接用bitmap即可,0表示存在,1表示不存在。
更多關於用bitmap來解決問題的博文:十七道海量資料處理面試題與bit-map詳解
、2-bitmap的使用關鍵在於如何操縱位,下面是乙個示例**:
#include #include #include #define n 1024*1024*1024
unsigned char bitmap[1 + n / 4]; //2-bitmap
void set(int x,int num)
void clear(int x)
unsigned get(int x)
void add(int x)
int main()
; //找出陣列a中不重複的元素
memset(bitmap, 0, sizeof(bitmap)); //清空位圖
for (int i = 0;i < 8; i++)
//現在可以檢視每個元素出現的次數
for (int i = 0;i < 8; i++)
printf("%d %d\n", a[i], get(a[i]));
putchar('\n');
//如果要判斷某個數x是否存在於陣列a中,直接判斷get(x)的值
//get(x) > 0 ? 存在 : 不存在
//下面的**輸出在a陣列中僅出現1次的數
for (int i = 0; i < 2;i++) //這裡實際上只需要用到16bit
for(int j = 0; j < 4; j++)
getchar();
return 0;
}
參考:
Bitmap和2 Bitmap海量資料處理問題
內容會持續更新,有錯誤的地方歡迎指正,謝謝 要解決上面的問題,都需可以用bitmap或2 bitmap。bitmap也就是位圖 引出bitmap 舉乙個小例子,有乙個無序整形陣列,也就占用記憶體3 4 12位元組,這很正常,但如果有1億個這樣的數呢?1億 4 1024 1024 1024 0.372...
大資料中2Bitmap的思想
2 bitmap main.cpp 在2.5億個整數中找出不重複的整數,注,記憶體不足以容納這2.5億個整數。下面都假定為非負整數!方案1 採用2 bitmap 每個數分配2bit,00表示不存在,01表示出現一次,10表示多次,11無意義 進行,共需記憶體2 32 2 bit 1 gb記憶體,還可...
Bitmap與Byte Drawable之間的轉換
1 bitmap 轉化為 byte bytearrayoutputstream out new bytearrayoutputstream bitmap.compress bitmap.compressformat.png,100,out byte array out.tobytearray 2 b...