海量数据处理-邮箱黑名单

来源:互联网 发布:动漫网站源码整套 编辑:程序博客网 时间:2024/05/21 10:32

题目说明:

输入要求:

共有两个文件,一个文件中包含2000万个email地址,每个email地址占文件中的一行;第二个文件中有1000个email,每个email地址占文件的一行。

输出要求:

输出一个1000行结果的文件,每行一个yes/no,表示1000个email是否在2000万email中。

分析:

海量字符串匹配问题,解决的算法有Trie树和Bloom Filter。Bloom Filter算法更容易理解,先用Bloom Filter来分析并解决问题。


Bloom Filter:

       Bloom Filter中文称布隆过滤器,它的思想类似于bit map的思想,它通过Hash函数将一个email映射到二进制数组中的某一位。如果该位已经被置为1,则表明该email已经存在。可以很容易想到不同的email可能经过hash后会得到同一个值,这就是冲突(碰撞)。解决方法主要包括:多引入一些相互独立的hash函数以及将位数组开大一点。

C++版本的代码链接:https://github.com/ToWorld/Bloom-Filter

Trie树:

Trie树的思想就是将字符串中的字符以结点的形式存放在树中,检查一个字符串是否存在时,只需要按照字符串中的每个字符进行遍历即可。因此这种算法的时间复杂度为O(n),其中n为待查询的字符串的长度。具体实现Trie树的比较有效的思想包括双数组思想以及前缀树思想。前缀树的思想更容易实现并且效率不低,下面先分析一个前缀树的思想并用C/C++实现。

前缀树经典的思路就是相同前缀的字符串只存一次。好处包括节省内存空间以及时间复杂度。因为节省内存空间的同时减少了动态申请内存的次数。当处理海量数据时,比如几千万,几个亿甚至更多时,动态申请内存的时间消耗是很大的。更多关于前缀树的讲解链接https://en.wikipedia.org/wiki/Radix_tree

C++版本的代码链接:https://github.com/ToWorld/Radix




0 0