海量数据处理相关算法简介

一、Hash映射/分治,数组的特点是寻址容易,但是插入删除困难,链表的特点是寻址困难,但是插入删除容易。而哈希表就是这两者的结合,寻址和插入删除都容易。左边是一个数组,数组每个成员包含一个指针指向一个链表的头。如图所示的就是一种求模数散列法。index=value%16


统计某日访问谷歌官网最多的IP,数据肯定是{时间:IP}形式的,只需统计每个IP出现的次数返回最大的即可。但是数据量往往非常大,内存加载不了,使用哈希函数/哈希映射将大文件分成一个个的小文件。这时候每个文件就可以加载进内存,统计每个小文件出现次数最多的IP,最后将所有小文件出现次数最多的IP互相比较得出整体访问官网次数最多的IP。

哈希映射,例如把大文件分成10000个小文件,对每个IP模10000,得到的值为k(0~9999),放入第k个文件当中。同时相同的IP一定会得到相同的k值,且都被存入k文件中,保证了每个IP都只存在于一个文件当中

二、Hash映射/分治

搜索引擎,现有1000万条检索字符串记录,每条字符串1~255个字节,要求找出检索热度最高的10个字符串。其中去掉重复的字符串大概剩余300万条记录,内存最大1G。解决方法依然是Hash映射的思想,数据总量10000000*1/4*1024字节=2500000KB=2500M=2.5G,超出内存限制。对每个字符串模3得到值k,k的范围0~2,将数据分别存入到0、1、2三个文件当中,这样每个文件都可以加载进内存。使用Hash统计,得到每个字符串总共检索的次数,最后使用堆排序得出检索热度最高的十个字符串。

最小堆排序,用前十个字符串出现的次数构建一个最小堆,然后堆顶元素跟剩下的每个字符串作对比,如果出现次数比堆顶元素小则不调整最小堆,如果比堆顶元素大则替换堆顶元素并重新调整最小堆,最终得到检索次数最多的十个字符串。

此类问题有一个关键点就是相同的IP或者字符串都应该在同一个文件或者机器上,否则需要首先用Hash映射(例如取模)将相同元素映射到同一个文件下,再进行Hash统计,最后归并排序结果(归并排序,采用分治思想,将待排序的序列分成许多部分,每两个部分从第一个元素开始两两比较得出较小值存入第三个空数组,得到一个排好序的新数组,将新数组与其他部分重复前面过程)

三、Trie树,利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希表高(适合数据量大,重复多,但是数据种类小可以放入内存)


一个大文件,每行一个单词,统计出现频次最高的十个单词。首先可以使用前面的Hash映射分治的方法,这里介绍另外一种基于Trie树的方法。如上所示,首先将所有单词构建Trie树,统计的时候检索Trie树是否存在这个单词,存在则计数加一。最后使用最小堆得到十个出现频次最高的单词。Trie树的时间复杂度为O(n*length),最小堆的时间复杂度为O[ n*lg(10) ]

四、Bitmap

Bitmap:假设有一组需要排序的数列 [4,6,9,1,2 ],因为最大值为9,所以需要开辟16个Bit位,大小2Byte。首先第一个元素4,应放在第五个Bit位,值设置为1。第二个元素6应放在第七个Bit位,并将位设置为1。最后遍历一遍Bit域便得到【1,2,4,6,9】

假设有2.5亿个整数,试找出2.5亿个整数中不重复的整数。用两个Bit位表示一个整数,没有出现00,出现一次01,出现多次10,11没有意义。总共2^32×2=1G内存,遍历2.5亿整数,将对应Bit位根据出现次数进行设置,最后输出Bitmap位为01的就可以了。

BloomFilter:假设存在AB两个文件,各包含50亿条URL,现在需要找出两个文件中共同的URL。假设每条URL占64字节(512Bit位),内存限制为4G。4G内存大概相当于320亿Bit位,首先将A文件中的URL映射到320亿Bit位中,例如映射方法为采用三个不同的Hash函数,得到三个不同的哈希值k1,k2,k3,并将对应Bit位设置为1,然后从文件B中取一个URL采用同样的三个Hash函数映射,如果得到的三个哈希值在前面的Bit位域中都设置为1了,说明这是一个AB文件中都包含的URL。

BloomFilter是一种空间效率很高的随机数据结构,它利用位数组很简洁地表示一个集合,并能判断一个元素是否属于这个集合。它是判断一个元素是否存在于某个集合的快速算法。BF可能会出现误判,如果BF认为一个元素不在集合中,那么肯定不在。如果在集合中,那么存在一定概率判断错误。


如上所示为一个m位的位数组,初始都为0。假设存在集合{x1,x2,x3......xn},布隆过滤器使用k个独立的哈希函数,它们将集合中的每个元素映射到m位数组中。在判断y是否属于集合时,使用k个哈希函数得到k个哈希值,然后将对应位置1,如图y1不属于这个集合,y2属于这个集合。Bloom filter将集合中的元素映射到位数组中,用k(k为哈希函数个数)个映射位是否全1表示元素在不在这个集合中。

五、MapReduce

包括map、reduce两个过程,最经典的例子就是wordcount了。假设我们有很多篇文章,每篇文章包含很多单词,单词在不同文章、同一篇文章有重复。

分布式文件系统HDFS,具有高容错性。HBase是一个分布式的、面向列的、可伸缩的数据库,其建立在HDFS上。

六、堆(最大堆求前n小,最小堆求前n大)


                                                                              如图所示就是最小堆

而二叉堆是一种完全二叉树,其任意子树的左右节点(如果有的话)的键值一定比根节点大。


二叉堆入队过程


二叉堆出队过程

七、双层桶

假设有5亿个int整数,找出他们的中位数。我们将int分为2^16=65536个区域,然后统计落在各个区域里的数,中位数就是第2.5个整数,这样就能找出中位数在哪个区域,之后在那个区域里再找中位数就可以了。

八、倒排索引

在前面的文本相似度计算、tf-idf、词向量的文章中已经详细介绍了VSM模型。汉语中构建的词向量可能很大,可能是几十万维度的,这个时候计算开销比较大。倒排索引被用来存储在全文搜索下某个单词在一个文档或者一组文档中的存储位置的映射,它是文档检索系统中最常用的数据结构。

文档1(D1):中国移动互联网发展迅速
文档2(D2):移动互联网未来的潜力巨大
文档3(D3):中华民族是个勤劳的民族


倒排索引数据结构汇总存储了两个重要信息,文档编号和单词出现的次数。当有一个查询时,分词之后根据倒排索引,得出文档之间的相似度。注意左侧的汉字可以换成GBK编码来加快查询速度。


参考资料:https://blog.csdn.net/he90227/article/details/38299975

                https://www.cnblogs.com/ECJTUACM-873284962/p/6910842.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值