C#位图BitArray 小试牛刀

共 2842字,需浏览 6分钟

 ·

2021-07-10 08:15

前面聊了布隆过滤器,回归认识一下位图BitMap,阅读前文的同学应该发现了布隆过滤器本身就是基于位图,是位图的一种改进。

难缠的布隆过滤器,这次终于通透了

位图

先看一个问题, 假如有1千万个整数,整数范围在1到1亿之间,如何快速确定某个整数是否在这个1千万个整数中呢?

乍一看是一个查找问题,循环、二分查找都是常规思路。

一个好的答案是数据结构和算法的完美结合, 基于题干上的特征和条件,我们是否有其他思路。

对于题干我们使用高中排列组合的思维:有1亿个按顺序编号的空篮子,我们拿出这1千万个有数字的球,放进对应的篮子。

最后,所有的篮子有两种状态:有球/无球,我们要确定某个数字是否存在,就看对应篮子是否为空。

什么是位图?每一位存放某种状态,适用于海量数据,通常用于判断数据是否存在。位图的空间由数据的最大值决定。

位图这种数据结构来大大节省内存的使用量。


我们只需要构造一个长度为1亿的bit数组,将有球位置标记为1,无球位置默认记为0;这样我们就将数字转换成了一个被压缩紧致的数组索引,1亿bit数组不到16M空间。

确定某位置有球,O(1)的时间复杂度。

C# 有专业的位图数组:BitArray

using System;using System.Collections;namespace Bitmap{    class Program    {        static void Main(string[] args)        {            var input = Console.ReadLine();            var num = int.Parse(input);            var bitmap = InitBitMap();            if (bitmap.Get(num))            {                Console.WriteLine($"找到数字{num}");            }            else            {                Console.WriteLine($"未找到数字{num}");            }        }        public static BitArray InitBitMap()        {            var myBA1 = new BitArray(10000);            var arr1 = new int[] { 1, 2, 4, 6, 77, 77, 88, 99, 100, 500, 600, 700, 999, 8888 };            foreach (int element in arr1)            {                myBA1[element] = true;            }            return myBA1;        }    }}

BitArray是管理位值的紧凑数组,用布尔值表示,其中true表示位是开启的(1),false表示位是关闭的(0), 是引用类型,位于System.Collections命名空间。

以上只是小试牛刀,我们针对原题再发散一下,如何找到以上1千万整数中重复的数字?

还是篮子中放球的思路,这次我们要两排篮子,也就是两个BitMap,利用位AND运算(同时为True,结果才是True)找到两排篮子中均有球的位置。

using System;using System.Collections;namespace Bitmap{    class Program    {        static void Main(string[] args)        {            var bitmap = InitBitMap();            for (int i = 0; i < bitmap.Length; i++)            {                if(bitmap[i] == true)                {                    Console.WriteLine(i);                }            }        }        public static BitArray InitBitMap()        {            var myBA1 = new BitArray(10000);            var myBA2 = new BitArray(10000);            var arr1 = new int[] { 1, 2, 4, 6, 77, 77, 88, 99, 100, 500, 600, 700, 999, 8888 };            foreach (int element in arr1)            {                if (myBA1[element] == false)                {                    myBA1[element] = true;                }                else                {                    myBA2[element] = true;                }            }            myBA1 = myBA1.And(myBA2);            return myBA1;        }    }}

最后提醒各位:宝藏组件Redis天然支持位图







回复 【关闭】广
回复 【实战】获取20套实战源码
回复 【被删】
回复 【访客】访
回复 【小程序】学获取15套【入门+实战+赚钱】小程序源码
回复 【python】学微获取全套0基础Python知识手册
回复 【2019】获取2019 .NET 开发者峰会资料PPT
回复 【加群】加入dotnet微信交流群

卧槽,你更新Win11了嘛?


去TM收费,我要在线 Vip 视频解析!



浏览 41
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报