對于海量資料這個詞,大家不難理解吧。主要是針對給定的資料量特別大,佔用記憶體特別大的情況。那麼和位元影像有什麼關係呢。看下面一個騰訊的海量資料的例子吧。
例:給40億個不重複的不帶正負號的整數,沒排過序。給一個不帶正負號的整數,如何快速判斷一個數是否在這40億個數中。
對於這道題,我們給了40億個不重複的不帶正負號的整數,一個整數是4個位元組,那麼就是40*4=160億個位元組,大概是16G的記憶體。顯然在記憶體上時存不下的。那麼我們怎麼來尋找呢。既然是不重複,就說明整數要麼就不出現,要麼就出現一次。整數的最大值是42億多,即2^32。此時我們就可以用每一位來表示這個數存在或者不存在。如果將32位為一個編號時,原本16G的資料使用位元影像可以節省到500M的空間。大概我們剛剛學過雜湊表,用訪問地址的方法來快速的尋找出地址對應的值。這裡也一樣,用到了雜湊表中的新的解決海量資料的方法---位元影像。
那麼問題來了。什麼是位元影像呢。
我們用每一位標誌這個數存在的狀態,設為0(不存在)和1(存在);
位元影像的基本結構:
是一個size_t類型的vector數組;
vector<size_t> _array;
位元影像的基本函數:
對於判斷一個不帶正負號的整數,是否存在這40億個數中。
(1)需要存入這40億個數,使用Set將對應的40億個位置為1;
(2)使用Test將判斷某個位是否為0或1;
註:位元影像只是考慮了整數類型
位元影像的實現代碼:(vs2013)
#pragma once#include<iostream>using namespace std;#include<vector>//位元影像的每一位的0,1標誌這個數存在或不存在的狀態class BitMap{public:BitMap(size_t Size = 1024){_array.resize(Size/32+1);}~BitMap(){}public://將這個數存在的狀態置為1void Set(const size_t& value){size_t index = value>>5;size_t bit = value % 32;_array[index] |= (1<<bit);}//將這個數不存在的狀態置為0void Reset(const size_t& value){size_t index = value>>5;size_t bit = value % 32;_array[index] &= (~(1<<bit));}//測試某個數是否出現過bool Test(const size_t& value){size_t index = value>>5;size_t bit = value % 32;return (_array[index] & (1<<bit));}private:vector<size_t> _array;};void BitMapTest(){BitMap bm(size_t(-1)); //64位系統下表示的整數的最大值bm.Set(10);bm.Set(100);bm.Set(20);bm.Set(500);cout<<bm.Test(10)<<endl;cout<<bm.Test(200)<<endl;cout<<bm.Test(500)<<endl;cout<<bm.Test(40)<<endl;}
運行結果: