Bit-map介紹及其應用

來源:互聯網
上載者:User

註:本文參考自 http://blog.csdn.net/v_JULY_v ,修正了其中的一些問題

感謝原作者


所謂的Bit-map就是用一個bit位來標記某個元素對應的Value, 而Key即是該元素。由於採用了Bit為單位來儲存資料,因此在儲存空間方面,可以大大節省。

如果說了這麼多還沒明白什麼是Bit-map,那麼我們來看一個具體的例子,假設我們要對0-7內的5個元素(4,7,2,5,3)排序(這裡假設這些元素沒有重複)。那麼我們就可以採用Bit-map的方法來達到排序的目的。要表示8個數,我們就只需要8個Bit(1Bytes),首先我們開闢1Byte的空間,將這些空間的所有Bit位都置為0

0 0 0 0 0 0 0 0

然後遍曆這5個元素,首先第一個元素是4,那麼就把4對應的位置為1(可以這樣操作 p+(i/8)|(0×01<<(i%8)) 當然了這裡的操作涉及到Big-ending和Little-ending的情況,這裡預設為Big-ending),因為是從零開始的,所以要把第五位置為一

注:原文的1的放置順序為從左至右,本人認為不妥,正確的順序為以從右向左的順序,原因如下: 在 setbit 函數中,採用的是 0x01<<j (左移)的方式,所以安裝正常邏輯應該是最右邊是最低位

0 0 0 1 0 0 0 0

然後再處理第二個元素7,將第八位置為1,,接著再處理第三個元素,一直到最後處理完所有的元素,將相應的位置為1,這時候的記憶體的Bit位的狀態如下:

1 0 1 1 1 1 0 0


然後我們現在遍曆一遍Bit地區,將該位是一的位的編號輸出(2,3,4,5,7),這樣就達到了排序的目的。下面的代碼給出了一個BitMap的用法:排序。

#include <stdio.h>#include <stdlib.h>#include <memory.h>//定義每個Byte中有8個Bit位#define BYTESIZE 8void setbit(char *p, int pos){    int i;    for(i=0; i<(pos/BYTESIZE); i++)    {        p++;    }    *p = *p | (0x01 << (pos %BYTESIZE));//將該Bit位賦值1    return;}void bitmap_sort_map(){    //為了簡單起見,我們不考慮負數    int num[] = {3, 5, 2, 10, 6, 12, 8, 14, 9};   //BufferLen這個值是根據待排序的資料中最大值確定的    //待排序中的最大值是14,因此只需要2個Bytes(16個Bit)    //就可以了。    const int BufferLen = 2;    char *pBuffer = (char*) malloc(BufferLen * sizeof(char));    //要將所有的Bit位置為0,否則結果不可預知。    memset(pBuffer, 0 , BufferLen);    int i,j;    for(i=0; i<9; i++)    {        //首先將相應Bit位上置為1        setbit(pBuffer, num[i]);    }    int bit_value,bit_verify;   //輸出排序結果    for(i=0; i<BufferLen; i++)//每次處理一個位元組(Byte)    {        for(j=0; j<BYTESIZE; j++)//處理該位元組中的每個Bit位        {            bit_value=*pBuffer & (0x01 << j);            bit_verify=0x01 << j;            //首先得到該第j位的掩碼(0x01<<j),將記憶體區中的            //位和此掩碼作與操作。最後判斷掩碼是否和處理後的            //結果相同            if(bit_value == bit_verify)            {                printf("%d ", i*BYTESIZE + j);            }        }        pBuffer++;    }    printf("\n");}int main(){    bitmap_sort_map();    return 0;}

注:原文中 在第二個for迴圈中

for(j=0; j < BYTESIZE; j++)

{

      if( *pBuffer & (0x01<<j) == (0x01<<j))

      {

       ..................

      }

}


可進行資料的快速尋找,判重,刪除,一般來說資料範圍是int的10倍以下


問題執行個體

1)已知某個檔案內包含一些電話號碼,每個號碼為8位元字,統計不同號碼的個數。

    8位最多99 999 999,大概需要99m個bit,大概10幾m位元組的記憶體即可。 (可以理解為從0-99 999 999的數字,每個數字對應一個Bit位,所以只需要99M個Bit==1.2MBytes,這樣,就用了小小的1.2M左右的記憶體表示了所有的8位元的電話)

2)2.5億個整數中找出不重複的整數的個數,記憶體空間不足以容納這2.5億個整數。

    將bit-map擴充一下,用2bit表示一個數即可,0表示未出現,1表示出現一次,2表示出現2次及以上,在遍曆這些數的時候,如果對應位置的值是0,則將其置為1;如果是1,將其置為2;如果是2,則保持不變。或者我們不用2bit來進行表示,我們用兩個bit-map即可類比實現這個2bit-map,都是一樣的道理。

參考:http://wansishuang.appspot.com/?p=35003


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.