一:簡介
所謂的bitmap就是用乙個bit位來標記某個元素對應的value, 而key即是該元素。由於採用了bit為單位來儲存資料,因此在儲存空間方面,可以大大節省。
二:基本思想
我們用乙個具體的例子來講解,假設我們要對0-7內的5個元素(4,7,2,5,3)排序(這裡假設這些元素沒有重複)。那麼我們就可以採用bitmap的方法來達到排序的目的。要表示8個數,我們就只需要8個bit(1bytes)。
(1)首先我們開闢1位元組(8bit)的空間,將這些空間的所有bit位都置為0,如下圖:
(2)然後遍歷這5個元素,首先第1個元素是4,那麼就把4對應的位置為1,因為是從零開始的,所以要把第5個位置為1(如下圖):
然後再處理第2個元素7,將第8個位置為1,,接著再處理第3個元素,一直到處理完所有元素,將相應的位置為1,這時候的記憶體的bit位的狀態如下:
(3)然後我們現在遍歷一遍bit區域,將該位是1的位的編號輸出(2,3,4,5,7),這樣就達到了排序的目的。
演算法思想比較簡單,但關鍵是如何確定十進位制的數對映到二進位制bit位的map圖。
三:map對映
假設需要排序或者查詢的總數n=10000000。
bitmap中1bit代表乙個數字
1個int = 4bytes = 4*8bit = 32 bit,那麼n個數需要n/32 int空間。所以我們需要申請記憶體空間的大小為int a[1 + n/32],其中:a[0]在記憶體中佔32為可以對應十進位制數0-31,依次類推:
bitmap表為:
a[0] ---------> 0-31
a[1] ---------> 32-63
a[2] ---------> 64-95
a[3] ---------> 96-127
..........
那麼十進位制數如何轉換為對應的bit位,下面介紹用位移將十進位制數轉換為對應的bit位。
申請乙個int一維陣列,那麼可以當作為列為32位的二維陣列。
例如:
十進位制1 在a[0]中,位置如下圖:
十進位制31 在a[0]中,位置如下圖:
十進位制32 在a[1]中,位置如下圖:
十進位制33 在a[1]中,位置如下圖:
通過上圖分析得出通過以下幾步將十進位制數如何轉換為對應的bit位:
(1)求十進位制數在對應陣列a中的下標
十進位制數0-31,對應在陣列a[0]中,32-63對應在陣列a[1]中,64-95對應在陣列a[2]中………
分析得出:對於乙個十進位制數n,對應在陣列a[n/32]中
例如n=11,那麼 n/32=0,則11對應在陣列a中的下標為0,n=32,那麼n/32=1,則32對應在陣列a中的下標為1,n = 106,那麼n/32 = 3,則106對應陣列a中的下標為3。
(2)求十進位制數在對應陣列a[i]中的下標
例如十進位制數1在a[0]的下標為1,十進位制數31在a[0]中下標為31,十進位制數32在a[1]中下標為0。
在十進位制0-31就對應0-31,而32-63則對應也是0-31,即給定乙個數n可以通過模32求得在對應陣列a[i]中的下標。
分析得出:對於乙個十進位制數n,對應在陣列a[n/32][n%32]中
(3)移位
對於乙個十進位制數n,對應在陣列a[n/32][n%32]中,但陣列a畢竟不是乙個二維陣列,我們通過移位操作實現置1。
a[n/32] |= 1 << n % 32
移位操作:
a[n>>5] |= 1 << (n & 0x1f)
n & 0x1f 保留n的後五位 相當於 n % 32 求十進位制數在陣列a[i]中的下標
/*--------------------------------
* 日期:2015-02-07
* 題目: bitmap
* 部落格:
------------------------------------*/
#include #include using namespace std;
#define n 1000000000
//申請記憶體的大小
int a[1 + n/32];
// 設定所在的bit位為1
void bitmap(int n)
// 判斷所在的bit為是否為1
bool exits(int n)
void show(int row)//for
cout<
for(int i = vec.size()-1;i >= 0;--i)//void
// 置0
void clearbitmap(int bitmap,int num)//void
// 獲取
bool getbitmap(int bitmap,int num)//void
// 統計**號碼個數
int phonecount(int phone,int n,int bitmap)//for
// 統計個數
int count = 0;
for(int i = 0;i < n;++i)//if
}//for
return count;
}int main()//for
// 隨機生成100個**號碼
srand((unsigned)time(nullptr));
for(int i = 0;i < num;++i){
phone[i] = rand() % n + min;
cout
待完善…….
引用:
演算法之海量資料處理
1.雜湊 分治 尋找共同的url 給定兩個a和b檔案,各存放50億個url,每個url佔64位元組,記憶體限制4gb,請找出a和b檔案中共同的url。乙個檔案的記憶體 5 000 000 000 64 320gb,每個檔案可以分為100個小檔案,每個檔案大約是3.2gb。1000萬個字串去重 假設每...
海量資料處理之Bitmap
什麼是bit map 所謂的bit map就是用乙個bit位來標記某個元素對應的value,而key即是該元素。由於採用了bit為單位來儲存資料,因此在儲存空間方面,可以大大節省。如果說了這麼多還沒明白什麼是bit map,那麼我們來看乙個具體的例子,假設我們要對0 7內的5個元素 4,7,2,5,...
海量資料處理 高階程式設計師之海量資料處理
何謂海量資料處理?所謂海量資料處理,無非就是基於海量資料上的儲存 處理 操作。何謂海量,就是資料量太大,所以導致要麼是無法在較短時間內迅速解決,要麼是資料太大,導致無法一次性裝入記憶體。那解決辦法呢?針對時間,我們可以採用巧妙的演算法搭配合適的資料結構,如bloom filter hash bit ...