算法通关村第十五关——超大规模数据场景白银挑战笔记

该部分主要优化位存储这一解题方法,实现以更小的存储空间解决超大规模数据问题!

1.从40亿个数中产生一个不存在的正整数

题目要求:给定一个输入文件,包含40亿个非负整数,请设计一个算法山剩一个不存在该文件中的整数,假设仅有1GB内存。

1.1位图存储大数据原理

倘若40亿个数字都不同,则哈希表的记录数为40亿,存储一个int类型数字需要内存4B,所以最差情况下需要160亿B,大约为16GB。

但是可以使用40亿个bit来表示这40亿个数字,比如0100表示数字3,40亿个bit就是5亿个B,大约为0.5GB。

数据结构设计完成后,先遍历一遍这40亿个数字,然后逐个标记位图;然后再次遍历位图,确定最终缺失的正整数。

1.2使用10MB内存

如果使用位图的方式,需要0.5GB内存,也就是512MB内存,但是目前最多可用10MB内存,该怎么办呢?答:分块,确定块号,确定块内位置

分块:最多可用10MB内存,因此每个块最大10MB,一般采用2的幂次方内存块大小,即选取每块大小为8MB,一共分成64块。

确定块号:第一块可以存储8MB个数字,也就是1<<26个bit,每个bit标记一个数字,因此第一块可以表示的数据范围是[0,1<<26 - 1],第二块[1<<26,1<<52 - 1]依次....。所以,块号=num/(1<<26)【当然使用位操作就是num的二进制表示的后面26位全部变成0】。

确定块内位置:块内位置=num%(1<<26)【当然用位操作就是仅保留num的二进制表示的最后26位】

数据结构设计完成之后,建立一个64大小的int数组countArr[64],每个countArr[i]表示第i个块内一共标记了几个数字,countArr[i]==1<<26时,该块存储已满,没有数据缺失;当countArr[i]<1<<26时,该块未满,发生数据缺失。然后我们二次遍历40亿个数字,只关注进入第i块内的数字,并对他们进行标记,遍历完成后找到缺失的位置就是就是缺失的数字(需要加上块起始偏置)。

1.3如何确定分块区间

前面我们提到使用位图需要512MB内存,我们最大的内存是10MB,因此可以选择8MB,当前我们可以选择更小的块4MB和2MB,但是需要注意,当设置的块较小时,countArr[]占用空间就会增大,需要防止countArr[]超出内存。

2.用2GB内存在20亿个整数中找到出现次数最多的数

需要使用哈希表进行存储{key就是数字,value就是数字出现次数},我们知道int类型表示的范围是[-1<<31,1<<31-1],因此key和value都可以使用int类型,按位记录数字和数字出现次数。因此,一条记录的大小就是8B,20亿个数字最多需要有20亿个记录,大小就是160亿B,大约为16GB。

分块:2亿个数字只需要1.6GB内存,因此可以将原来的20亿个数字划分成10块,我们可以将其划分成8块(每块2GB)或16块(每块1GB),以划分成16块为例:

确定块号:每块内存1GB,最多可以存储1<<29条记录(大约5亿条记录),因此第一块可以表示的数据范围是[0,1<<29 - 1],第二块[1<<29,1<<58 - 1]依次....。所以,块号=num/(1<<29)

确定块内位置:该位置是指块中的第几条记录,块内位置=num%(1<<29)

数据结构设计完成之后,先便利一遍20亿个数字,仅保留第一块中的记录,找出第一个块中出现次数最多的数字保存,然后再次遍历,仅保留第二块中的记录,找到第二个块中出现次数最多的数字保存,依次....最后就得到各块出现次数最多的数字,找到16个较多出现的数字中出现次数最多的数字就是20亿个数字中出现次数最多的数字。

3.从100亿个URL中查找的问题

题目:有一个包含100亿个URL的大文件,假设每个URL占用64B,请找出所有重复的URL

补充问题:某搜索公司一天的用户搜索词汇是百亿数据量,请设计一种求出每天热门Top 100词汇的可行办法。

第一个题目,可以将100亿B的大文件通过哈希函数分配到100台机器上,每台机器分别统计自己的URL中是否存在重复的。或者将大文件拆分成小文件,对每一个小文件再利用哈希表遍历,找出重复的URL。

大数据问题离不开分流,要么用哈希函数将大文件内容分配给不同的机器,要么用哈希函数将大文件拆成小文件,然后处理每一个小数量的集合。

对于补充问题,可以将发文件拆分成小文件,通过哈希表统计每种词及其词频,哈希表记录建立完成后,在利用容量为100的小根堆筛选小文件中的Top100,然后再用容量为100的小根堆,筛选较大词频的Top 100个词。

4.40亿个非负整数中找到出现两次的数

题目:32位无符号整数的范围是0~4 294 967 295,即1<<32-1,现在最多使用1GB内存,找出所有出现两次的数字。

可以使用两位来记录非负整数出现次数 00表示出现0次、01表示出现1次、10表示出现2次、11表示出现3次及以上。那么只需要1<<32个2bit数据就可以完成数字及其出现次数的存储。即需要1<<33bit=1<<30B=1GB内存。

OK,《算法通关村第十五关——超大规模数据场景白银挑战笔记》结束,喜欢的朋友三联加关注!关注鱼市带给你不一样的算法小感悟!(幻听)

再次,感谢鱼骨头教官的学习路线!鱼皮的宣传!小y的陪伴!ok,拜拜,第十五关第三幕见!

你可能感兴趣的:(算法,笔记)