BitMap算法

BitMap?

BitMap你可能会想到位图文件,但在算法中也有个叫BitMap的数据结构,常利用在压缩、爬虫系统中url除重、解决全组合问题,经常被用在解决海量数据寻找重复数据或者判断数据是否存在该集合的问题。

一道经常出现的面试题

面试经常会问:给一台配置是2G内存,要处理一个包含40亿个不重复并且没有排过序的整数。那么问题在于,给出一个整数,怎么快速这个整数是否在这40亿数据中呢?

思考:40亿int占40亿*4/1024/1024/1024大概占15G左右,2G内存肯定加载不了,但这个问题最好的方案肯定是放在内存里去判断集合是否存在该元素。

解决思路:如何在2G内存存储15G数据,一个int在C中是占4个字节的即要32bit位,如果能够用一个bit位来标识一个int整数那么存储空间将大大减少,算一下40亿个int需要的内存空间为40亿/8/1024/1024大概为476.83 mb,这样的话我们完全可以将这40亿个int放到内存中进行处理。

BitMap映射表

1个int占4字节即4*8=32位,那么我们只需要申请一个int数组长度为 int tmp[1+N/32]即可存储完这些数据,其中N代表要进行查找的总数,tmp中的每个元素在内存在占32位可以对应表示十进制数0~31。

简单来说就是一个数组的加一位索引代表进一位,byte[0] = 0~31,byte[1]=32~63,byte[2]=64~95,以此类推。其图示如下:

转换成表格为:

 

以上算法关键的点在于如果判定数字在BitMap中的位置,其实有个很简单的方法就是直接除以32得到的整数倍 - 1是BitMap的索引,然后除以32取整数部分(即取模运算)就可以得到在该索引下该数字的位置。

Java代码

由于Java本身带有BitMap的Api,这里就不累赘写多一次,代码如下:

总结

BitMap是一种很常用的数据结构,比如用在BloomFilter中,或者用于无重复整数的排序等等。由于BitMap对内存的占用极小,经常在大数据中被优化使用,在算法实现中也是比较简单、经典的算法,值得大家一试。

————————————————————

原文:http://baijiahao.baidu.com/s?id=1579317011375934540&wfr=spider&for=pc

posted @ 2019-01-30 15:56  舞羊  阅读(211)  评论(0编辑  收藏  举报