bitmap是一個十分有用的結構。所謂的Bit-map就是用一個bit位來標記某個元素對應的Value, 而Key即是該元素。由於採用了Bit為單位來儲存資料,因此在儲存空間方面,可以大大節省。
適用範圍:可進行資料的快速尋找,判重,刪除,一般來說資料範圍是int的10倍以下
基本原理及要點:使用bit數組來表示某些元素是否存在,比如8位電話號碼
擴充:bloom filter可以看做是對bit-map的擴充
問題執行個體:
1)已知某個檔案內包含一些電話號碼,每個號碼為8位元字,統計不同號碼的個數。
8位最多99 999 999,大概需要99m個bit,大概10幾m位元組的記憶體即可。
2)2.5億個整數中找出不重複的整數的個數,記憶體空間不足以容納這2.5億個整數。
將bit-map擴充一下,用2bit表示一個數即可,0表示未出現,1表示出現一次,2表示出現2次及以上。或者我們不用2bit來進行表示,我們用兩個bit-map即可類比實現這個2bit-map。
下面是一個簡單的Bitmap的實現:
複製代碼 代碼如下:
#include "stdafx.h"
#include <iostream>
using namespace std;
char *g_bitmap = NULL;
int g_size = 0;
int g_base = 0;
//功能:初始化bitmap
//參數: size:bitmap的大小,即bit位的個數
// start:起始值
//傳回值:0表示失敗,1表示成功
int bitmap_init(int size, int start)
{
g_size = size/8+1;
g_base = start;
g_bitmap = new char[g_size];
if(g_bitmap == NULL)
{
return 0;
}
memset(g_bitmap, 0x0, g_size);
return 1;
}
//功能:將值index的對應位設為1
//index:要設的值
//傳回值:0表示失敗,1表示成功
int bitmap_set(int index)
{
int quo = (index-g_base)/8 ; //確定所在的位元組
int remainder = (index-g_base)%8; //位元組內的位移
unsigned char x = (0x1<<remainder);
if( quo > g_size)
return 0;
g_bitmap[quo] |= x; //所在位元組內的特定位置為1
return 1;
}
//功能:取bitmap第i位的值
//i:待取位
//傳回值:-1表示失敗,否則返回對應位的值
int bitmap_get(int i)
{
int quo = (i)/8 ;
int remainder = (i)%8;
unsigned char x = (0x1<<remainder);
unsigned char res;
if( quo > g_size)
return -1;
res = g_bitmap[quo] & x;
return res > 0 ? 1 : 0;
}
//功能:返回index位對應的值
int bitmap_data(int index)
{
return (index + g_base);
}
//釋放記憶體
int bitmap_free()
{
delete [] g_bitmap;
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
int a[] = {5,8,7,6,3,1,10,78,56,34,23,12,43,54,65,76,87,98,89,100};
int i;
bitmap_init(100, 0);
for(i=0; i<20; i++)
{
bitmap_set(a[i]);
}
for(i=0; i<=100; i++)
{
if(bitmap_get(i) > 0 )
cout << bitmap_data(i)<< " ";
}
cout << endl;
bitmap_free();
return 0;
}
【問題執行個體】
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,都是一樣的道理。