位圖介紹(bitmap)


1、位圖(Bitmap)簡介

    位圖是一種非常常見的結構,它使用每個二進制位來存放一個值的狀態,正因為這個性質,它經常被用在數據壓縮或者是索引等方面。

    有這樣一道題:給40億個不重復的無符號整數,沒有經過排序,然后再給一個樹,如何快速判斷這個數是否在40億個數之中?在這里如果我們實打實的存放40億個數據在內存中,那會占據將近15個G的內存,普通電腦根本無法滿足,更不用說在對其進行查找操作了。 那么如果選擇位圖來存儲的話我們只需要差不多500M就夠了。大大的節省了內存的消耗。

    如下圖,我們把1表示存在狀態,0表示不存在,那么該組數據中就標記了2和5兩個數存在                   
                                 

 

 

2、C++位圖實現

  位圖結構需要自己實現,C++並沒有現成的數據結構可以用

  

  一個int類型整數占4個字節,一共32位,可以標記32個數的狀態,因此,我們把一個整數占用的內存叫做一個單元,一個單元標記32個數據的狀態

  

  我們對一個數據進行標記之前需要先確定在那個單元,N/32

 

  在確定在該單元的第幾位上 N%32

 

  確定位置之后改變狀態

  (0-->1) ,采用或運算 

    (1-->0)    ,采用與運算

 

  

#include<iostream>
#include<string.h>
#include<algorithm>
#include <vector>
#include<bitset>
using namespace std;
class BitMap
{
public:
    //初始化位圖的大小,range是要保存的數據個數,1個int數據可以標記32個狀態,因為位圖是不支持擴容操作的
    //所以一開始要確定好位圖的大小
    //比如要標記1000個數據的狀態,需要開int類型的數組大小為1000/32+1
    BitMap(size_t range)
    {
        _bits.resize((range >> 5) + 1);
    }
    //在位圖中標記第N個數據
    void Set(size_t N)
    {
        //先確定在那個單元
        size_t index = N >> 5;
        //在確定在該單元的什么位置
        size_t bitNum = N % 32;
        //或運算對原來為1的狀態沒有影響,方便我們改變第N個數的狀態
        _bits[index] |= (1 << bitNum);
    }

    //在位圖中的第N個數據標記置零
    void Reset(size_t N)
    {
        size_t index = N >> 5;
        size_t bitNum = N % 32;
        //假設bitNum=3,則1<<3  =  1000
        // 取反操作     ~(1000) = 0111
        _bits[index] &= (~(1 << bitNum));
    }
    //判斷第N個數是否被標記
    bool check(size_t N)
    {
        //假設N=9,9>>5相當於9/(2^5)
        size_t index = N >> 5;
        //bitNum=9
        size_t bitNum = N % 32;
        //_bits[0]=  00000000 00000000 00000010 00000000
        //_bits[0>>9=00000000 00000000 00000000 00000001
        return (_bits[index] >> bitNum) & 1;
    }
private:
    vector<int> _bits;
};


int main()
{
    BitMap bs(1001);
    bs.Set(5);
    bs.Set(63);
    bool ret = bs.check(33);
    if (ret)
    {
        cout << "它在" << endl;
    }
    else
    {
        cout << "它不在" << endl;
    }
    /*bitset<32>t1(~(9 >> 5));
    bitset<32>t2(1 << 9);
    cout << t1<< endl;
    cout << t2 << endl;*/
    system("pause");
    return 0;
}

 

 

轉載自https://blog.csdn.net/MOU_IT/article/details/89106308?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-4.channel_param

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM