C++面试总结之算法(五):海量数据

1.. 布龙过滤器,主要还是检查一个数据是否在海量数据中的方法

(1)应用场景

字处理软件中,需要检查一个英语单词是否拼写正确

在 FBI,一个嫌疑人的名字是否已经在嫌疑名单上

在网络爬虫里,一个网址是否被访问过

yahoo, gmail等邮箱垃圾邮件过滤功能

(2)布隆过滤器原理:

布隆过滤器(Bloom Filter)的核心实现是一个超大的位数组和几个哈希函数。假设位数组的长度为m,哈希函数的个数为k。具体的操作流程:假设集合里面有3个元素{x, y, z},哈希函数的个数为3。首先将位数组进行初始化,将里面每个位都设置位0。

对于集合里面的每一个元素,将元素依次通过3个哈希函数进行映射,每次映射都会产生一个哈希值,这个值对应位数组上面的一个点,然后将位数组对应的位置标记为1。

(3)布隆过滤器添加元素:

将要添加的元素给k个哈希函数

得到对应于位数组上的k个位置

将这k个位置设为1

(4)布隆过滤器查询元素

将要查询的元素给k个哈希函数,得到对应于位数组上的k个位置

如果k个位置有一个为0,则肯定不在集合中

如果k个位置全部为1,则可能在集合中

注意:此处不能判断该元素是否一定存在集合中,可能存在一定的误判率。假设某个元素通过映射对应下标为4,5,6这3个点。虽然这3个点都为1,但是很明显这3个点是不同元素经过哈希得到的位置,因此这种情况说明元素虽然不在集合中,也可能对应的都是1,这是误判率存在的原因。

2. 腾讯面试题:给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中? 

(1)方案1:

申请512M的内存,一个bit位代表一个unsigned int值。读入40亿个数,设置相应的bit位,读入要查询的数,查看相应bit位是否为1,为1表示存在,为0表示不存在。

(2)方案2:

因为2^32为40亿多,所以给定一个数可能在,也可能不在其中;这里我们把40亿个数中的每一个用32位的二进制来表示。假设这40亿个数开始放在一个文件中。

  然后将这40亿个数分成两类: 1.最高位为0 2.最高位为1 并将这两类分别写入到两个文件中,其中一个文件中数的个数<=20亿,而另一个>=20亿(这相当于折半了);与要查找的数的最高位比较并接着进入相应的文件再查找

再然后把这个文件为又分成两类: 1.次最高位为0 2.次最高位为1,并将这两类分别写入到两个文件中,其中一个文件中数的个数<=10亿,而另一个>=10亿(这相当于折半了); 与要查找的数的次最高位比较并接着进入相应的文件再查找。 ....... 以此类推,就可以找到了,而且时间复杂度为O(logn),方案2完。

(3)方案3

位图法: 使用位图法判断整形数组是否存在重复、判断集合中存在重复是常见编程任务之一,当集合中数据量比较大时我们通常希望少进行几次扫描,这时双重循环法就不可取了。

  位图法比较适合于这种情况,它的做法是按照集合中最大元素max创建一个长度为max+1的新数组,然后再次扫描原数组,遇到几就给新数组的第几位置上1,如遇到5就给新数组的第六个元素置1,这样下次再遇到5想置位时发现新数组的第六个元素已经是1了,这说明这次的数据肯定和以前的数据存在着重复。这种给新数组初始化时置零其后置一的做法类似于位图的处理方法故称位图法。它的运算次数最坏的情况是2N。如果已知数组的最大值即能事先给新数组定长的话效率还能提高一倍。

3. 在我们使用淘点点时,怎么查找最近100家商户,数据量大;说出算法思想,要求效率高;

海量数据推荐博客:https://blog.csdn.net/v_july_v/article/details/7382693

写的特别棒!!!

猜你喜欢

转载自blog.csdn.net/lxin_liu/article/details/89308041