第一部分、从一道题,漫谈数据结构、以及压缩、位图算法(转载)
海量数据处理往往会很有趣,有趣在什么地方呢?
- 空间,aliveable的内存不够,需要反复交换内存
- 时间,速度太慢不行,毕竟那是海量数据
- 处理,数据是一次调用还是反复调用,因为针对时间和空间,通常来说,多次调用的话,势必会增加预处理以减少每次调用的时候的时间代价。
题目如下
7、腾讯面试题:给40亿个不重复的unsignedint的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中?
分析:1个unsigned int占用4字节,40亿大约是4G个数不到,那么一共大约要用16G的内存空间,如果内存不够大,反复和硬盘交换数据的话,后果不堪设想。
那么怎么储存这么多的数据呢?还记得伴随数组么?还是那种思想,利用内存地址代替下标。
先举例,在内存中应该是1个byte=8bit,那么明显有
0 = 0000 0000
255 = 1111 1111
69 = 0100 0101
那么69可以表示0.2.6三个数存在,其余的7以下的数不存在,0表示0-7都不存在,255表示0-7都存在,这就是位图算法:通过全部置0,存在置1,这样一种模式来通过连续的地址存贮数据,和检验数据的方法。
那么1个 unsigned int代表多少个数呢?1个unsigned int 是一个2^32以内的数,那么也就是这样的1个数,可以表示32个数是否存在。同理申请一个unsigned int的数组a[n]则可以表示连续的(n+1)*32的数组。也就是a[0]表示0-31的数是否存在,a[2]表示32-63的数是否存在,依次类推。
这时候需要用多大的内存呢?
16g/32=512M
512M和16G之间的区别,却是是否一个32位寻址的CPU能否办得到的事儿了,众所周知,32位CPU最大寻址不超过4G,固然,你会说,现在都是64位的CPU之类的云云,但是,对于底层的设计者来说,寻址范围越小越好操控的事实是不争的。
问题到这里,其实基本上已经完事了,判断本身,在位图算法这里就是找到对应的内存位置是否为1就可以了。