位图和海量数据问题
什么是位图?
问题:
有40亿个数,未排序,设计程序能很快的判断出一个个数据在不在其中。如果直接将者40亿个数放在内存中那么需要 40亿*4字节 = 160亿字节,大概是2^34字节,也就是2^4GB空间,16G内存,抱歉,我的电脑只有8G内存,那此时应该怎么办呢?
思考:我们会发现我们只是为了表示在与不在,那我们为什么要这么大的空间呢?完全可以用一个位来代表40亿中的一个数字不就行了?如果这个位位1,那就说明在,位为0,说明不在,这样的话4G内存就足够了,而这种思想就叫做位图。
哈希切割问题
给一个超过100G大小的log file,log中存折ip地址,设计算法找到出现次数最多的IP地址?
- 进行文件切割
- 设计一个hash函数
- 让同样的IP进入同样的小文件
- 分别为每个小文件进行求Top1问题
- 求N个IP的TOP1问题
注意问题:
- hash不是均匀分布,top1的ip数量所占的内存大于我的内存怎么办?
解法:文件切割的时候如果发现一个IP所占的空间较大,那就给此IP再分一个小文件,最后记得一起统计就行了
海量数据
位图应用
给定100亿个整数,设计算法找到只出现一次的整数。
- 只需要统计三种情况即可:
- 没有出现过
- 只出现一次
- 出现超过一次
- 所以一个数需要2个比特位来存储状态
- 可以用两个一位的位图搭配来实现,但是设置位图的时候需要同时考虑两个位图
- 也可以用一个两位的位图。
用两个一位的位图
- 没有出现过设定为: 位图1 = 0 位图2 = 0
- 出现过一次的设定为: 位图1 = 1 位图2 = 0 或者 位图1 = 0 位图2 = 1
- 出现次数超过两次的设定为:位图1 = 1 位图2 = 1
- 将得出的两个位图最后按位异或(~)最后哪位为1,说明此位对应的整数出现了一次
2.给定两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件的交集
- 两个位图分别统计两个文件: 1代表有,0代表没有
- 最后将两个位图按位与,结果为1的为说明两个文件都存在。
位图变形
一个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数。
与上一题类似:
状态有:
- 没有出现过: 位图1=0,位图2=0
- 出现了一次: 位图1=0,位图2=1
- 出现了两次: 位图1=1,位图2=0
- 出现了两次以上:位图1=1,位图2=1
需要四位存储 ,最后将两个位图按位与,求出的位为0的代表出现的次数不超过2次
海量数据问题解决思路
- 通过Hash函数分文件(通用,分治(分而治之))
- 位图的方式处理(信息压缩)