大数据问题



在学习C语言阶段,大家肯定都写过这样的一个程序:求一个数的阶乘。细心的同学,可能在编码的时候,会注意这个数的情况~如果给定数据过大,阶乘的结果可能会溢出~关于比较大的数的阶乘,我们就会采取别的办法~关于具体的代码,之后的文章将会为大家分享~ 
再如,学习堆的时候,我们遇到这样的问题:N个数据中求取最大的前K个数,如果N不是很大,我们可以采取快排,然后选取的办法来解决~如果N很大,可以选择分组或者建堆的方式来解决~这种问题之前都已经解决~ 
然而,我们还会遇到这么一类问题:找出两个大文件的交集等等这样的问题~下边,我将会对哈希这块遇到的大数据问题做以分析~ 
1.给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集。 
分析:整形数,不管是有符号数还是无符号数,总共有2^32个数字,也就是4G,(100亿个数中肯定有重复的),我们可以采用位图来解决,4G个数总共占用512MB内存(下边给出计算过程),1G内存是完全够用的。我们可以将第一个文件里的数据映射到位图中,再拿第二个文件的数字去到第一个文件映射的位图中去对比,有相同就是交集~(重复的数字,交集中只会出现一次)这里写图片描述


2.假定一个文件有100亿个整形数,1G内存,如何找到出现次数不超过两次的数字。 
分析:要想找到出现次数不超过两次的数字,每个数字设置一个位是不够的(一个位只能表示是否存在),所以我们可以考虑两个位: 
根据题目的要求,我们可以借助两个位,来表示数字的存在状态及存在次数:00表示不存在,01表示存在1次,10表示存在2次,11表示存在超过两次。根据上边一道题目的分析:如果一个数字占一位,需要512M内存就可以;如果一个数占两位(一个整形的32位只能表示16个数了),1G内存就可以了。将所有的数字映射到位图中,查找不是11的所对应的数字就好了~ 
题目改变假如只给定512M内存,如何完成上述问题。 
思路:将所有的数据分批处理,由于是有符号数,我们可以先处理正数,再处理负数,这样,512M内存可以解决上述问题的。


3.给定两个文件,分别包含100亿个字符串,如何快速的找出两个文件的交集~ 
分析:一看到字符串,我们立刻想到布隆过滤器来处理这个问题,布隆过滤器可以粗略的表示一个字符串是否在海量字符串中(注意是粗略,因为布隆过滤器是有一定的误判率)。如果想要准确的找到两个字符串文件的交集,我们可以将大文件进行分割,将一个一个的小文件分别拿到内存中去比对,找到交集。 
布隆过滤器的详细解决办法:根据不同的字符串哈希算法,将字符串可以计算出不同的几个key值,然后进行映射,这样可以映射到不同的几个位置,只有当这几个位同时为1时,这个串才是有可能出现,只要有一个位是0,那么这个串一定是不存在的。将第一个文件进行映射到布隆过滤器中,拿第二个文件的每个串,去进行比对(计算出串的key,找到映射的位,看是否全部是1,如果是1,大致认为这个串是两个串的交集,如果有0,则这个串一定不是交集)这个办法就是一种近似的算法~ 
文件分割的详细解决办法:我们可以将100G的字符串(假如每个字符串占10字节,所有的字符串全部导入内存会占:2.5 * 40G * 10 == 25G内存(40G的数据,一个一字节,大约占1G内存)),所以我们将两个文件分别分割成大小相同的100个文件,然后用第二个文件的每一个小文件进行与文件1中的每个小文件进行比对,这样文件2中的每个字符串都要与文件1中的每一个字符串进行比较,这样的话,效率就是比较低的。那么我们能不能将相似或者相同的字符串分在一个文件中才减少比较次数~ 
回想:在前边的一篇文章《找到一组数字的“单身”》这篇文章中,有问题:假如其他数字都出现两次,如何找到只出现一次的两个数字,我们就是将所有的数字进行分组,分组依据:根据某个比特位是0还是1,是0分到一组,是1分到另一组,这样相同的数字就会出现在一个组内,查找方便。(注明:分组依据写的比较简单,不是特别清楚这个问题的读者,点文末的链接自行学习~)那么根据上边题目的思路,我们可以根据字符串的某个哈希算法,将得到的字符串的key值,将key值进行模要分割的文件数(此处给1000,并对每个文件分割的小文件进行编号,0~999),结果相同的就放置在一个文件中,这样相同的字符串就会放置在同一个文件中(两个文件中相同的字符串通过同一个字符串哈希函数,会被分到文件下标一样的文件中),这样,我们只需要将下标相同的两个文件进行比对就好了~~ 
这样时间复杂度就会明显降低,时间复杂度是O(N)。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值