數據結構之BITMAP

我們先給出之前我看過的騰訊公司的一道筆試題,引出位圖BitMap。


給40億個不重複的無符號整數,沒排過序。給一個無符號整數,如何快速判斷一個數是否在這40億個數中。


這個問題怎麼解決呢?


1)將40億數據保存起來(保存在數組、鏈表、樹中),再和該數判斷是否相等。

那我們思考一下需要多少內存:

技術分享

技術分享

2)藉助位圖BitMap解決。


位圖(BitMap)

是用一個數組中的每個數據的每個二進制位表示一個數是否存在。1表示存在,0表示不存在。

相當於把數組分成很多塊的空間,每一塊是32個比特位。

原來32個比特位放一個數據,現在一個位就可以放一個數據。16GB/32=0.5GB=512MB。


 位圖的實現:


#ifndef __BITMAP_H__
#define __BITMAP_H__
#include<iostream>
using namespace std;

#include<vector>

class BitMap
{
public:
    BitMap(size_t size = 0)
        :_size(0)
    {
        //_a開闢多一個空間,如size=36/32=1,需要兩塊空間才能放下
        _a.resize((size >> 5) + 1);
    }


    void Set(size_t x)
    {
        //size_t index = x / 32;
        size_t index = (x >> 5);
        size_t num = x % 32;

        //if(!(_a[index] & (1 << num))表示該二進制位不存在,則該位二進制置成1
        if (!(_a[index] & (1 << num)))
        {
            _a[index] |= (1 << num);
            ++_size;
        }
    }


    void Reset(size_t x)
    {
        //size_t index = x / 32;
        size_t index = x >> 5;
        size_t num = x % 32;

        //該位存在則將該位二進制置爲0
        if (_a[index] & (1 << num))
        {
            _a[index] &= ~(1 << num);
            --_size;
        }
    }


    bool Test(size_t x)
    {
        //size_t index = x / 32;
        size_t index = x >> 5;//獲取索引值
        size_t num = x % 32;//獲取索引值內的位置
        if (_a[index] & (1 << num))//某一位是否存在 0代表不存在  1代表存在
        {
            return true;
        }
        return false;
    }


    void Resize(size_t size)
    {
        _a.resize(size);
    }
private:
    vector<size_t> _a;
    size_t _size;
};

#endif //__BITMAP_H__
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章