解决大数据方面的问题

来源:互联网 发布:说明域名注册的流程 编辑:程序博客网 时间:2024/05/17 07:12

       在生活中我们往往会遇到一些大数据方面的题,那么遇到这些看似不太难但数据非常大的问题时我们又该如何来解决呢?下面我便来做一个简单的整理:

1、给超过100G大小的log file,log中存着ip地址,设计算法找到出现次数最多的ip地址?

       100G的文件中存的是ip地址,我们如何来找到出现次数最多的ip地址呢?普通的方法肯定是行不通的,这时候我们便需要解决大数据问题最常规的方法--文件分割文件分割却是可以解决这种大数据方面的问题,但是如何进行分割却又成为了新的问题,我们为了提高切分的效率便选择了哈希切分。

解决方案:

    采用哈希切分我们会将所有的ip经过同一个散列函数进行处理,那么相同的ip便会进入同一个文件当中,然后再统计每个文件中出现最多的ip的出现次数,那么便会知道出现次数组多的ip。

    采用这种方法还会有一个问题就是当我们把所有的ip都经过同一个散列函数分割到一个文件中,这个文件还是太大了,那么便将这个文件分成多份再使用哈希表,汇总其相同ip出现的次数。

2、与上题条件相同,如何找到top k的ip?如何直接用linux命令实现?

解决方案:

    这个问题的解法和上一个问题的解法基本上是相同的,我们还是要进行哈希切分,找出每个文件中ip出现的次数,然后再建一个小堆找出每个文件中出现次数最多的k个ip。然后进行汇总这时候堆里面出现次数最多的k个ip就是要找的这个。(直接用linux命令来实现的方式我后面会进一步的补充)

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

解决方案:

    方案1:哈希切分

        我们可以将这个文件进行哈希切分将这些数据大概分到100个文件中去,这样每个文件的大小就大概是400mb,这时我们就可将这些数据加载到哈希表中去,然后就会知道那个数据是只出现一次的数据。

    方案2:位图

                            在前面给大家介绍过位图(bitmap),在位图中用0表示一个数不存在,用1来表示这个数是存在的。在这里需要对位图做一个扩展就可以,我们用两个位,00(不存在),01(出现一次),10和11就表示这个数出现一次以上。这样就可以通过位图来解决这个只出现一次的问题,而且只需要1G的空间就能放下这些数。

bitmap:    点击打开链接(需要了解位图的可点此链接)

    方案3:

        整数有32个位,按最高位为0和最高位1讲这些数分成两部分,继续每一位都这样进行分,直到最后一位。查找哪个文件中只有一个数,这样就会找到。

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

    100亿个整数大概要占40G

    方法1:

    将一个文件分割成100份,然后把这100份文件都加载到内存中去,用第二份文件中的数据到每一份文件中进行查找,这样能找到两文件的交集。不过其时间复杂度就为O(n^2)。

    方法2:

    使用哈希切分的方法,将一个文件数据使用一个哈希函数进行切分,这样相同的数一定会进入同一个文件当中去,然后进行编号。对另外一个文件也是用相同的哈希函数进行切分,这样我们只需要将相同编号里的文件进行比较。这样其时间复杂度就会降低为O(n)。

    方法3:

    将一个文件中的数据全部映射到位图中去,大概只要500mb的空间。再用第二个文件中的数据到第一个映射的图中进行对比,相同的数字就是存在交集 这种方法的时间复杂度为O(n)。

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

    这道题的解法与第三题极为类似(可以参照第三题

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

精确算法哈希切分

     如果要找到精确的两个文件的交集,我们就要使用哈希切分来完成。在进行哈希切分之前要将query类型先经过相同的散列函数(BKDR散列函数)处理使这些数据先转化为整型数据,再用散列函数进行切分这样相同的数一定会进入同一个文件当中去,然后进行编号。对另外一个文件也是用相同的哈希函数进行切分,这样我们只需要将相同编号里的文件进行比较。时间复杂度为O(n)。

近似算法:布隆过滤器

    用近似的算法找到这两个文件的交集可以使用布隆过滤器(BloomFilter)。先将query类型通过相同的散列函数(BKDR散列函数)处理是这些数据先转化为整形数据,将第一个文件中的数据映射到这个位图中去(大概要512mb)再让第二个文件中的数据去这个位图中进行查找,找到的便是交集。

布隆过滤器(BloomFilter):点击打开链接(需要了解布隆过滤器的点此链接

7、如何扩展BloomFilter使得它支持删除元素操作?如何扩展BloomFilter使得它支持计数操作?

   关于布隆过滤器中删除元素的操作和计数操作可点击上方链接,对于布隆过滤器删除操作有着详细的说明

8、给个上千个文件,每个文件大小为1k-100m。给n个词,设计算法对每个词找到所有包含它的文件,只有100k内存。

    对于这个问题还得要用到布隆过滤器来进行操作,有上千份文件就要有上千个布隆过滤器,并将这上千个布隆过滤器存到一个文件中去。将内存分为两部分,一部分用来进行读取一个布隆过滤器,还有一部分用来读取文件。对每个读进去的单词判断是否包含这个单词。如果不包含就读取下一个文件,如果包含的话就把这个词和这个词对应的文件信息存到一个专门的文件中去。直到所有的词已经读完。

9、有一个词典,包含N个英文单词,现在给任意一个字符串,设计算法找出包含每个字符串的所有英文单词。

解决方法:字典树

    我们对于这种问题可以用字典树来进行解决。字典树又称:单词查找树,这种树形结构是哈希树的一种变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来节约存储空间,最大限度地减少无谓的字符串比较,查询效率比哈希表高。

    首先要把这N个单词建立一颗字典树,再用给定的单词去这棵树中进行查找,找到就记录想用的英语单词,没有找到的话那么这棵树中就不包含这个单词。在这颗树比较深的情况下,就会比较浪费内存,可以用哈希表把这棵树n层以后的数据存放到哈希表中去,这样就会节省内存空间。

   

    对于大数据方面的问题还有很多,上面我只是列出了一部分而已。但是思想与解决方法基本也就如此,我们在解决此类问题的时候都可以将其转化为:文件分割+数据结构。再加上哈希表、位图、布隆过滤器等等就可以充分解决这些问题。只不过具体问题还要不同的数据结构来进行解决。

1 0