zoukankan      html  css  js  c++  java
  • 位图介绍(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

  • 相关阅读:
    设备树实践
    设备树实例解析
    设备树语法
    设备树基本概念
    设备树中#address-cells和#size-cells作用
    Linux设备驱动详解 宋宝华 硬件基础
    jffs2镜像制作
    ltp-ddt eth_iperf_tcp iperf dualtest遇到的问题
    shell 函数传递参数的几种方式
    windows logstash配置
  • 原文地址:https://www.cnblogs.com/-citywall123/p/13460398.html
Copyright © 2011-2022 走看看