题目:我有 40 亿个整数,再给一个新的整数,我需要判断新的整数是否在 40 亿个整数中,你会怎么做(每个整数是32位的)?

一个数在不在就是两个状态,在或者不在,就可以用1个位来代表。

每个整数是32位的,那么所有的整数也就2^32个,大概42亿个数左右。

可以申请2^32的位,把每一个整数都覆盖了,40亿个数的位分别为1,剩下的位为0。

新的整数,就可以跟进它的大小来判断相应的位,比如1245,就去看1245位是1还是0来判断是否在这40亿个整数中。

最后需要也就是500M左右。

如果我给你 2GB 的内存,并且给你 20 亿个 int 型整数,让你来找出次数出现最多的数,你会怎么做?

可以把这 20 亿个数映射到不同的文件中去,例如,数值在 0 至 2亿之间的存放在文件1中,数值在2亿至4亿之间的存放在文件2中....,由于 int 型整数大概有 42 亿个不同的数,所以我可以把他们映射到 21 个文件中去,如图

海量数据问题

把每个数先做哈希函数映射,根据哈希函数得到的哈希值,再把他们存放到对应的文件中

每个文件采用哈希表来统计,把这个数作为 key,把这个数出现的次数作为 value,之后我再遍历哈希表哪个数出现最多的次数最多就可以了

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

分而治之/hash映射:针对数据太大,内存受限,只能是把大文件化成(取模映射)小文件;按照IP地址的Hash(IP)%1000值,把海量IP日志分别存储到1000个小文件中。这样,每个小文件最多包含4MB个IP地址

hash_map统计:当大文件转化了小文件,那么我们便可以采用常规的hash_map(ip,value)来进行频率统计。

堆/快速排序:统计完了之后,可以得到1024个小文件中的出现次数最多的IP,再依据常规的排序算法得到总体上出现次数最多的IP;

有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1M。返回频数最高的100个词。

分而治之/hash映射:顺序读文件中,对于每个词x,取hash(x)%5000,然后按照该值存到5000个小文件(记为x0,x1,…x4999)中。这样每个文件大概是200k左右。如果其中的有的文件超过了1M大小,还可以按照类似的方法继续往下分,直到分解得到的小文件的大小都不超过1M。

hash_map统计:对每个小文件,采用trie树/hash_map等统计每个文件中出现的词以及相应的频率。

堆/归并排序:取出出现频率最大的100个词(可以用含100个结点的最小堆)后,再把100个词及相应的频率存入文件,这样又得到了5000个文件。最后就是把这5000个文件进行归并(类似于归并排序)的过程了。

相关文章:

  • 2021-06-29
  • 2021-11-24
  • 2021-09-05
  • 2021-06-10
猜你喜欢
  • 2021-12-03
  • 2021-12-14
  • 2021-04-26
相关资源
相似解决方案