每日一題——位圖

定義:位圖(bitmap)就是利用每一位來存儲某種狀態,但是狀態又比較少的情況。
缺點:
1,只能用於整形;
2,可讀性差;
3,位圖存儲的元素個數雖然比一般做法多,但是存儲的元素大小受限於存儲空間的大小。位圖存儲性質:存儲的元素個數等於元素的最大值。比如, 1K 字節內存,能存儲 8K 個值大小上限爲 8K 的元素。(元素值上限爲 8K ,這個侷限性很大!)比如,要存儲值爲 65535 的數,就必須要 65535/8=8K 字節的內存。要就導致了位圖法根本不適合存 unsigned int 類型的數(大約需要 2^32/8=5 億字節的內存)。
4,位圖對有符號類型數據的存儲,需要 2 位來表示一個有符號元素。這會讓位圖能存儲的元素個數,元素值大小上限減半。 比如 8K 字節內存空間存儲 short 類型數據只能存 8K*4=32K 個,元素值大小範圍爲 -32K~32K

應用:
1,給定100億個整數,找出其中只出現過一次的整數; (1G:10億字節,所以存放需要320G)
思路:將100一個數拆成1000份,再將每份使用位圖,使用兩位bit表示數字出現的次數(00:沒出現過的數,01:出現一次的數,10:出現多次的數),再講次數爲1的合併到一個文件即可。
2,給兩個分別有100億個整數的文件,但是內存只有1G,找出兩文件的並集;
思路:1,暴力求解O(N);2,排序+遍歷O(NlgN);3,布隆過濾器(哈希+位圖);4,哈希切分
3,一個沒有排過序,有40億個不相同的無符號整數,如何在其中快速判斷是否有一個給定的值;
4,使用位圖法進行整型數組排序。
思路:遍歷數組找到max,min。根據這兩個值縮小位圖範圍,注意對於int的負數轉換爲無符號整數,且取位時數字減去最小值。
實現:

class BitMap
{
public:
    BitMap()
    {}
    BitMap(size_t size)
    {
        _table.resize((size >> 5) + 1);
    }
    void Set(int data)   //置1
    {
        size_t ByteNo = data >> 5;        //數組中的那個元素
        size_t BitNo = data % 32;         //32位bit位的那個bit位
        _table[ByteNo] |= (1 << BitNo);   //置1
    }
    void ReSet(int data)   //置0
    {
        size_t ByteNo = data >> 5;
        size_t BitNo = data%32;
        _table[ByteNo] &= ~(1 << BitNo);
    }
    bool IsIn(int data)
    {
        size_t ByteNo = data >>5;
        size_t BitNo = data%32;
        if(_table[ByteNo]&(1 << BitNo))
            return true;
        return false;
    }
private:
    vector<int> _table; 
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章