海量数据问题

哈希切割top K问题

  • 给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址? 与上题条件相同,如何找到top K的IP?

(1)文件太大,100G,肯定不可能一次加载到内存进行处理,这里就必须将文件进行切割了,可是依据哪种方法进行切割呢?假设只是从前到后等份切割的话,将文件切割n份(切割的份数依据所给的内存大小),第一份中假设IP地址为a出现次数最多,第二份中b出现的次数最多,这样比较出来,假设a比b大,那得出的结果就是IP地址为a的出现次数多,可是?假设第一份中也有地址为b的IP呢?这样分割出来的文件,不能保证相同IP地址被分到同一个文件当中,这样算出的结果就肯定不正确了。

这里我们应该想到使用哈希的思想,我们可以给出n个文件,(n的取值取决于给定的内存大小),将点分十进制的IP地址转化为整数,利于哈希函数(哈希函数采用直接定址法),求出IP地址所对应文件的编号,这样将所有地址分派到不同编号的文件中,相同的地址一定在同一个文件当中,依次遍历每个文件,统计出每个IP地址出现的次数,这样就可以找到出现次数最多的IP地址。

(2)top K问题的解决办法我们很容易想到用,首先,搞清楚是要出现次数最多的K个IP还是出现次数最少的K个IP。如果是最多的,可以给小堆,如果最少的,给的就是大堆;假设这里我们要的是出现次数最多的K个IP,在第一问中,我们已经求出了每个IP地址出现的次数,将这些IP地址和出现次数封装为一个结构体(键值对),给一个只能容纳K个键值对的小堆,在向堆中插入元素时,IP地址出现的次数作为关键码,先向堆中插入K个元素,以后再插入元素时,先于堆顶元素进行比较,如果小于堆顶元素,不做处理;如果大于,则将堆顶元素删除,将此元素重新插入堆中,当遍历完所有IP地址后,堆中保存的元素就是出现次数最多的K个。

  • 海量日志数据,提取出某日访问百度次数最多的那个IP

①分治:IP是32位,共有2^32个IP。访问该日的日志,将IP取出来,采用Hash,比如模1000,把所有IP存入1000个小文件。

②Hash_map:统计每个小文件中出现频率最大的IP,记录其频率。

③小顶堆:这里用一个变量即可。在这1000个小文件各自最大频率的IP中,然后直接找出频率最大的IP。

  • 海量数据分布在100台电脑中,想个办法高效统计出这批数据的TOP10。

分析:虽然数据已经是分布的,但是如果直接求各自的Top10然后合并的话,可能忽略一种情况,即有一个数据在每台机器的频率都是第11,但是总数可能属于Top10。所以应该先把100台机器中相同的数据整合到相同的机器,然后再求各自的Top10并合并。

①分治:顺序读每台机器上的数据,按照Hash(x)%100重新分布到100台机器内。接下来变成了单机的topk问题。单台机器内的文件如果太大,可以继续Hash分割成小文件。

②Hash_map:统计每台机器上数据的频率。

③小顶堆:采用容量为10的小顶堆,统计每台机器上的Top10。然后把这100台机器上的TOP10组合起来,共1000个数据,再用小顶堆求出TOP10。

  • 100w个数中找出最大的100个数。

方法1:用容量为100的小顶堆查找。复杂度为O(100w * lg100)。小堆是最好的方法。

方法2:采用快速排序的思想,每次分割之后只考虑比标兵值大的那一部分,直到大的部分在比100多且不能分割的时候,采用传统排序算法排序,取前100个。复杂度为O(100w*100)。

方法3:局部淘汰法。取前100个元素并排序,然后依次扫描剩余的元素,插入到排好序的序列中,并淘汰最小值。复杂度为O(100w * lg100) (lg100为二分查找的复杂度)。

  • 给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件共同的url?

分析:每个文件的大小约为5G×64=320G,远远大于内存大小。考虑采取分而治之的方法。

①分治:遍历文件a,对每个url求Hash%1000,根据值将url分别存储到1000个小文件中,每个小文件约为300M。文件b采用同样hash策略分到1000个小文件中。上述两组小文件中,只有相同编号的小文件才可能有相同元素。

②Hash_set:读取a组中一个小文件的url存储到hash_set中,然后遍历b组中相同编号小文件的每个url,查看是否在刚才构建的hash_set中。如果存在,则存到输出文件里。

  • 一个文件包含40亿个整数,找出不包含的一个整数。分别用1GB内存和10MB内存处理。

1GB内存:

①Bitmap:对于32位的整数,共有2^32个,每个数对应一个bit,共需0.5GB内存。遍历文件,将每个数对应的bit位置1。最后查找0bit位即可。

10MB内存: 10MB = 8 × 10^7bit

①分治:将所有整数分段,每1M个数对应一个小文件,共4000个小文件。注意计算机能表示的所有整数有4G个。

②Hash_set:对每个小文件,遍历并加入Hash_set,最后如果set的size小于1M,则有不存在的数。利用Bitmap查找该数。

注:计算机能表示的整数个数一共有4G个,整数域hash分割成10M一个文件,,一共分割成400个小文件,每个小文件判断不存在的数,再把这些数全都归并起来。磁盘IO次数越少越好!!所以不明白为啥1M对应一个小文件,而不取最大的10M。

位图应用

  • 给定100亿个整数,设计算法找到只出现一次的整数

假设这里是32位机,32位机中整形所能表示数字最大个数为2的32次方,我们可以使用位图来表示一个数的状态,每个数给两个比特位,00表示这个数不存在,01表示这个数出现一次,10表示这个数出现多次,这样所需空间大小为1G(2^64bit)

  • 给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集

与第一问一样,我们可以使用位图思想,这里只需要一个比特位来表示一个数存在与否,将两个文件的数据分别映射到两个位图当中,将两个位图按位与,得出的结果就是两个文件的交集。

  • 1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数

与第一问一样,也是用两个比特位表示一个数据的状态。00表示不存在,01表示只出现一次,10表示出现两次,11表示出现两次以上,将每个数据映射到位图当中,最后遍历位图,就可以得出结果。

布隆过滤器

  • 给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?分别给出精确算法和近似算法

精确算法:
一个query(查询记录)字符串大概算60字节,100亿大概600G,那么我们可以进行哈希切割,给出6000(数目越多,越不容易发生哈希冲突,结果越准确)个文件,将字符串转化为整数,采用除留余数法,将每个字符串保存到对应编号的文件当中,然后再遍历第二个文件,拿到一个字符串,用相同的办法找到它所对应的文件,再到对应的文件当中找是否有与其相同的字符串,这样就找到了两个文件的交集。

近似算法:
可以采用布隆过滤器,(即位图与哈希联系起来),将第一个文件当中的每一个字符串插入到布隆过滤器当中,然后,再到第二个文件当中,遍历每一个query,到布隆过滤器中查找词条query中是否存在。这样就可以近似找到两个文件的交集。因为,在布隆过滤器中查找某一个元素,如果查找结果位不存在,那么就一定不存在,但是如果结果为存在,其实也有可能不存在,所以这种解法位近似算法。

  • 如何扩展BloomFilter使得它支持删除元素的操作

可以给每一个元素分配多个比特位,例如:每个元素分配两个比特位,00表示不存在,01表示有一个,10表示有两个,如果要删除某个元素,给其减一,如10变为01。

  • 如何扩展BloomFilter使得它支持计数操作

与上题思路一致。

倒排索引

  • 给上千个文件,每个文件大小为1K~100M。给n个词,设计算法对每个词找到所有包含它的文件,你只有100K内存 。

可以将每个文件中的词都插入到布隆过滤器中,再用所给的n个词再布隆过滤器中查找。

typedef struct FileNode{
    int fileno;//文件编号
    int count;//出现次数
    struct FileNode *pNect;
}FileNode;

typedef struct HashNode{
    FileNode *pHead;
    struct HashNide*pNode;
}HashNode;

typedef strut HashTable{
    HashNode**array;
    int capacity;
    int size;
    //哈希函数
}HashTable;
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值