1. 程式人生 > >點陣圖bitmap

點陣圖bitmap

1、點陣圖定義 點陣圖法就是bitmap的縮寫。所謂bitmap,就是用每一位來存放某種狀態,適用於大規模資料,但資料狀態又不是很多的情況。通常是用來判斷某個資料存不存在的。在STL中有一個bitset容器,其實就是點陣圖法,引用bitset介紹: A bitset is a special container class that is designed to store bits (elements with only two possible values: 0 or 1,true or false). The class is very similar to a regular array, but optimizing for space allocation: each element occupies only one bit (which is eight times less than the smallest elemental type in C++: char).Each element (each bit) can be accessed individually: for example, for a given bitset named mybitset, the expression mybitset accesses its fourth bit, just like a regular array accesses its elements. 2、資料結構 unsigned int bit[N]; 在這個數組裡面,可以儲存 N * sizeof(int) * 8個數據,但是最大的數只能是N * sizeof(int) * 8 - 1。假如,我們要儲存的資料範圍為0-15,則我們只需要使得N=1,這樣就可以把資料存進去。如下圖:

資料為【5,1,7,15,0,4,6,10】,則存入這個結構中的情況為

3、相關操作 3.1寫入資料 定義一個數組:unsigned char bit[8 * 1024];這樣做,能存 8K8=64K 個 unsigned short 資料。bit 存放的位元組位置和位位置(位元組 0~8191 ,位 0~7 )(81024=8192) 比如寫 1234 ,位元組序: 1234/8 = 154; 位序: 1234 &0b111(得到除8的餘數) = 2 ,那麼 1234 放在 bit 的下標 154 位元組處,把該位元組的 2 號位( 0~7)置為 1 位元組位置: int nBytePos =1234/8 = 154; 位位置:int nBitPos = 1234 & 7 = 2; 3.2讀指定位 bool getbit(int bitmap1, int i){ return bitmap1[i >> SHIFT] & (1 << (i & MASK)); } 4、點陣圖法的缺點 1、可讀性差 2、點陣圖儲存的元素個數雖然比一般做法多,但是儲存的元素大小受限於儲存空間的大小。點陣圖儲存性質:儲存的元素個數等於元素的最大值。比如, 1K 位元組記憶體,能儲存 8K 個值大小上限為 8K 的元素。(元素值上限為 8K ,這個侷限性很大!)比如,要儲存值為 65535 的數,就必須要 65535/8=8K 位元組的記憶體。要就導致了點陣圖法根本不適合存 unsigned int 型別的數(大約需要 2^32/8=5 億位元組的記憶體)。 3、點陣圖對有符號型別資料的儲存,需要 2 位來表示一個有符號元素。這會讓點陣圖能儲存的元素個數,元素值大小上限減半。 比如 8K 位元組記憶體空間儲存 short 型別資料只能存 8K

4=32K 個,元素值大小範圍為 -32K~32K 。 4、點陣圖法的應用 1、給40億個不重複的unsigned int的整數,沒排過序的,然後再給一個數,如何快速判斷這個數是否在那40億個數當中。 首先,將這40億個數字儲存到bitmap中,然後對於給出的數,判斷是否在bitmap中即可。 2、使用點陣圖法判斷整形陣列是否存在重複 遍歷陣列,一個一個放入bitmap,並且檢查其是否在bitmap中出現過,如果沒出現放入,否則即為重複的元素。 3、使用點陣圖法進行整形陣列排序 首先遍歷陣列,得到陣列的最大最小值,然後根據這個最大最小值來縮小bitmap的範圍。這裡需要注意對於int的負數,都要轉化為unsigned int來處理,而且取位的時候,數字要減去最小值。 4、在2.5億個整數中找出不重複的整數,注,記憶體不足以容納這2.5億個整數 參考的一個方法是:採用2-Bitmap(每個數分配2bit,00表示不存在,01表示出現一次,10表示多次,11無意義)。其實,這裡可以使用兩個普通的Bitmap,即第一個Bitmap儲存的是整數是否出現,如果再次出現,則在第二個Bitmap中設定即可。這樣的話,就可以使用簡單的1- Bitmap了。