• 位图的基本原理以及应用


    位图的应用场景

    假设生活中有以下这种应用场景:有未排序的40亿个数,需要在其中查找一个数字是否存在。如果直接使用数组来存放这些数,那么一个整型的数占4个字节,40亿个数需要16G的内存大小,从空间上来说一般很难实现,更不用说如果要进行排序产生的损耗等问题了。那有没有什么好方法来存放这么大量的数据呢?这种时候可以用到位图。

    位图的基本概念

    所谓位图,就是用每一位来存放某种状态。一个字节有8位,那么每一位都可以用来存放某个数字是否存在。一般单个位图虽然适用于海量数据,但是遇到重复数据只能记录一次存在,不过如果使用多个位图也可以解决数据出现次数问题。下面来看看位图具体是怎么做的

    位图

    在这里插入图片描述
    这里是C++库里面对位图的介绍,那么为了更深刻的理解位图,可以自己来简单实现一下。实现代码如下:这里需要注意的是数组里面存放的是char占一个字节,也就是8位,用来表示状态的话相当于可以存放8个数据,因此在开空间的时候,将需要的数据大小除以8,这样一来原本需要16G左右的数据现在仅需要0.5M即可(原来数据是用int保存int占4个字节)。为了开足够的空间,这里在除以8之后再加上1。
    后面简单实现的3种功能:设置和取消设置某个数的状态以及判断一个数是否存在。
    这里的关键点在于需要确定某个数应当存放的vector数组的下标,用该数与8取模即可得到。然后该数存放的比特位位置,使用该数除8也可以得到,然后使用位运算符进行计算即可。

    	template<size_t N>
    	class bitset
    	{
    	public:
    		bitset()
    		{
    			_bits.resize(N / 8 + 1, 0);
    		}
    		void Set(size_t x)//设置为1
    		{
    			size_t i = x / 8;//确定该数字存储位置
    			size_t j = x % 8;//确定该数字存在该char类型的第几个位
    			_bits[i] |= (1 << j);
    		}
    
    		void Reset(size_t x)//设置为0
    		{
    			size_t i = x / 8;//确定该数字存储位置
    			size_t j = x % 8;//确定该数字存在该char类型的第几个位
    			_bits[i] &= (~(1 << j));
    		}
    
    		bool test(size_t x)//判断是否存在
    		{
    			size_t i = x / 8;//确定该数字存储位置
    			size_t j = x % 8;//确定该数字存在该char类型的第几个位
    			return _bits[i] & (1 << j);
    		}
    
    	private:
    		vector<char> _bits;
    	};
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    测试代码如下:

    	void test_bit_set()
    	{
    		bitset<100> bs;
    		bs.Set(5);
    		bs.Set(10);
    		bs.Set(20);
    		cout << bs.test(5) << endl;
    		cout << bs.test(10) << endl;
    		cout << bs.test(20) << endl;
    
    
    		bs.Reset(20);
    		bs.Reset(10);
    		bs.Reset(5);
    		cout << bs.test(5) << endl;
    		cout << bs.test(10) << endl;
    		cout << bs.test(20) << endl;
    
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    运行结果如下:
    在这里插入图片描述

  • 相关阅读:
    【深度学习】实验12 使用PyTorch训练模型
    RepVGG:让VGG风格的ConvNet再次伟大起来
    YOLO V5、SAM、RESNET50模型在GPU环境下搭建过程
    冥想第九百七十七天
    狄克斯特拉算法求最短路径
    【狂神】SpringMVC笔记(一)之详细版
    docker常用命令:docker制作镜像过程中常用的命令
    leetcode做题笔记2216. 美化数组的最少删除数
    python入门(10)面向对象 :类的特殊方法
    JS有哪些基本数据类型,它们的区别?
  • 原文地址:https://blog.csdn.net/h1091068389/article/details/126213398