数据结构:大数据处理问题

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

①方法一
100亿个整数就是400亿个字节,42亿九千万是4G,那么1G就是10亿字节,所以要存下100亿个整数需要40G的内存空间。因此我们采用位图100亿个整数大概就是1G,但是使用位图,需要用两个位标识一个数字(两个位可以标识四种状态),没有出现过为00,出现一次为01,出现两次及以上为10,11可以丢弃。所以2G空间就够了。
那么现在我们要找到只出现一次的整数就找到位图中映射01的那个数据即可。

②方法二
采用两个位图,每个位图是1G的大小,两个位图对应的位标识一个数据,两个位图对应的位都是0表示没有出现过;第一个位图对应位0,第二个位图对应位1则表示这个数只出现了一次;第一个位图对应位1,第二个位图对应位0则表示这个数出现了两次或两次以上。

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

①方法一
我们开一个位图,把第一个文件中的数字set到位图中,用第二个文件进行查找test,如果第二个文件中的数据在位图中被找到了,那么这个数就是交集的一份子,当把第二个文件中的数据查找完时就可以找到交集了。

②方法二
开两个位图,把文件1的数据set到位图1中,把文件2的数据set到位图2中,然后把两个位图进行与操作,那么与出来的结果位图中对应位为1的位所对应的数据的集合就是交集。

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

出现次数不超过2次的所有整数,一共有四种状态,因此需要用两个位来进行标识,00标识没有出现,01表示出现一次,10表示出现两次,11表示出现两次以上。找出现次数不超过2次的就是查找对应标识位为00,01,10的数据。

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

①近似算法
使用布隆过滤器,把文件1的query全部set到布隆过滤器里,然后用文件2的query进行test操作,如果返回true则说明这个query是交集的一份子,那么查找完就可以找出交集。
这样使用布隆过滤器可能会有误判,所以这个是近似算法。

②精确算法
假设每个query是40字节,那么一个文件的大小就是400G,此时把这个文件哈希切成1024份(注意:这里切多少份是要根据实际情况来定的,比如我是400G,切成1000多份,那么每一份大概就是400M,400M对内存来说是足够的)。
在这里插入图片描述
我们把文件A和文件B都切分成1024份小文件,切分采用的是哈希切分,如上图所示,用hash算法计算出来的num是多少就进入多少号小文件,然后将A和B文件对应的小文件进行找交集即可,因为是哈希切分,所以如果A文件和B文件如果有相同的query那么用同样的哈希算法就会让这两个相同的query分别进入A和B相同num的小文件里,所以在进行查找交集的时候只需要A0找B0,A1找B1这样子找下去。

查找小文件的交集时,可以把Anum的query映射到哈希表里,然后用Bnum的query去查找看有没有,如果有那么这个query就是交集的一份子,如果没有说明这个query不是交集的一份子。

5.布隆过滤器如何支持删除

如何支持
采用引用计数,但是采用引用计数删除的话就需要进行储存这个计数,需要额外的空间,会增大占用内存的大小。使用引用计数就是有多个值同时映射这个位,就把这个位的引用计数++,删除时就–,然后判断是否存在则是看值是否大于0。

引用计数开多大
那么这个引用计数开多少个字节呢?如果给一个字节,八个位,那最多就是有256个值映射同一个位置,那么少量数据还可以,如果是几百亿的数据的话,这个引用计数就是不够的。那如果给两个字节,16个位,那最多就可以有65535个值同时映射同一个位。如果给四个字节,32个位,那最多就可以有42亿九千万个值同时映射同一个位。所以引用计数开多少字节要根据实际情况来确定。

举例
假如用两个位来记录引用计数时,我们可以这样设计:vector<short> bits,也就是如果要设置(set)对应的位时,不采用置1操作,采用的是++操作,那么有值要进行映射时,对应位++即可。要删除(reset)对应的映射关系时,对应位的值–即可。如果要看在不在(test)时,那么直接看对应的映射位是不是0即可,如果是0则说明不在,如果是非零则说明在。

6.给一个超过100G大小的log文件,里面存着IP地址,设计算法找到次数最多的IP地址?

这个题看到之后我们就会知道这是top K问题,那么这个题要统计次数,首先想到map或者unorderd_map,key是IP地址,value是次数,但是100G的文件加载不到内存中去,所以我们采用哈希切分。
在这里插入图片描述
将log文件哈希切分成1024份,那么相同的IP地址就会进入编号相同的小文件里,那么我们只需要统计每个小文件里相同的IP地址出现的次数即可,因为相同的ip地址一定会进入同一个小文件。这里一个小文件大概就是100M,加载到内存中采用map或者unorderd_map统计次数即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章