如何判断一个元素在亿级数据中是否存在? 很难吗...
这两天看博客园首页一篇文章,https://www.cnblogs.com/crossoverJie/p/10018231.html
主要是分析一个面试题:
现在有一个非常庞大的数据,假设全是 int 类型。现在我给你一个数,你需要告诉我它是否存在其中(尽量高效)。
虽然文章给的布隆过滤器不能解决面试的这个题的问题,判断不存在和判断存在是两码事。
下面给出我的思路,欢迎大家讨论分析。
先假定有1亿个正整数,如何处理。如何初始化这1亿个数,使得来一个数就能快速分析出结果呢?
很直观的一种方法就是某个数存在就给它标记为1,否则标记为0,先假定有一个int.Max长的数组,每个数的值放到它的序号上,比如第一个数是5,那么就在第5位置1,其余类似。
如果用int数组,这样的话,这个数组就很长了,内存可能吃不消。
其实0、1这样的用比特存储就刚刚好,那么每8位的比特合在一起,就是一个byte,每一个byte加一个序号(表示是第几个8位)就能表示8个数是否存在了。那么如果用byte数组长度就是:1亿/ 8 = 12500000长的byte数组即可,这个数组的序号就是第N*8-N*8+8个数的分布情况。比如要查100是否存在这1亿数据中,对100除8取结果和余数,结果确定序号,判断序号对应的数的二进制在余数位是否为1即可。
同理,用int可以存32个数,就是1亿/32长的int数组;用long可以存64个数,就是1亿/64长的long数组即可。
无论是用byte、int还是long数组,大小都查不到,约: 1亿/ 32 * 4 / 1024 / 1024 ≈ 12(MB),也就是说用这么一点内存即可解决问题。
对于负数的处理,无非再用一个数组来存下即可。
那么如果数据多于1亿,比如10亿,百亿甚至更多怎么办呢?
很简单,存在数据库里面嘛,一个表俩字段(序号+值)即可,建个索引,很容易就能支持海量数据的处理了,这样扩展性的问题也就解决了。
一时兴起写的,排版请见谅。欢迎大家讨论。