演算法系列之十八 海量資料處理之BitMap

2021-09-29 22:24:27 字數 3611 閱讀 9180

一:簡介

所謂的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 ...