(1)给一个超过100G大小的log file,log中存着IP地址,设计算法找到出现次数最多的IP地址?
解题思路:IP地址是一个32位的字符串,100G在内存中肯定放不下,所以我们必须通过不同的手段去解决。我们可以将100G的文件切分成1000个小文件,对每个文件编号,每个文件的大小是512M,这样内存是很容易读取的。我们将IP地址通过字符串哈希函数处理成对应的整树,将整数模上文件个数(1000),对其取余,余数是几就放在编号为几的文件里。(这样,相同的IP肯定会出现在同一个文件里)分好之后,取每个文件中IP次数出现最多的IP进行比较,这时候问题转化成了1000个IP次数找次数出现最多的一个IP。
(2)与上题条件相同,如何找到top K的IP?如何直接用Linux系统命令实现?
解题思路:前半部分的处理和上题一样,后半部分处理不同的是,我们先建立一个堆(注意要建立小堆)。每个文件寻找出前K个出现次数较多的IP,1000分文件都找出前K个次数较多的IP,最后1000K个IP中在继续小堆查找判断,最后还是能找出前K个次数出现较多的IP
(3)给定100亿个整数,设计一个算法找到只出现一次的整数。
解题思路:整数一共有42亿多个,100亿个数中一定有重复的数字。
1M = 1024K = 2^10K
1K = 1024B = 2^10B
1B = 1024b = 2^10b
故:1G = 2^10M
= 2^10 * 2^10B
= 2^10 * 2^10 * 2^10b
如果一个整数占用一个字节,那么1G的内存可以处理约10亿的整数,一共有42亿多个无重复的整数,那么就需要4G的内存。1byte = 8位,每个位判断该数字存在与不存在,那么就需要4G/8 = 512M的内存,内存占用率大大降低,提高了效率。
然而,一个位只能表示这个数存在与否,不能断定这个数出现了几次。这个时候,我们应该考虑用两个位来存放一个数的状态。00表示这个数出现了0次,01表示这个数出现了1次,10表示这个数出现了多次,11状态我们暂且不用。最后,我们找出状态是01的数就可以了。
那么,这样占多少内存呢?一个位处理42亿多个整数占用了512M的内存,那么两个位处理42亿多个整数占用了1G的内存。如果这个时候,考官还想你500M左右处理这道题呢?那么,我们可以考虑正整数和负整数分开处理,也可以达到考官的要求。
(4)给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件的交集?
解题思路:给定1000个小文件,每个小文件都编号。对A,B两个大文件的100亿个数切分,每个数对1000取余,余数为几就放在编号为几的文件中。最后比较的时候,我们只取编号相同的小文件去比较。(将100亿个数分到1000个小文件中,每个文件大小512M,每次取A,B文件进行比较,两个文件刚好1G,符合题意)
(5)一个文件有100亿个int,1G内存,设计算法找出出现次数不超过2次的所有整数。
解题思路:这道题和第3题的解题思路是一样的,也是设置两个位来存放一个数的状态,00表示不存在,01表示出现一次,10表示出现两次,11表示出现多次。这时候我们只有知道状态为01或者10的数就可以了。两个位表示所需要占用的内存为1G(计算过程参考第三题)
(6)给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?给出精确算法和近似算法。
解题思路:
精确算法:同第四题的思路相同
近似算法:布隆过滤器
解题思路:IP地址是一个32位的字符串,100G在内存中肯定放不下,所以我们必须通过不同的手段去解决。我们可以将100G的文件切分成1000个小文件,对每个文件编号,每个文件的大小是512M,这样内存是很容易读取的。我们将IP地址通过字符串哈希函数处理成对应的整树,将整数模上文件个数(1000),对其取余,余数是几就放在编号为几的文件里。(这样,相同的IP肯定会出现在同一个文件里)分好之后,取每个文件中IP次数出现最多的IP进行比较,这时候问题转化成了1000个IP次数找次数出现最多的一个IP。
(2)与上题条件相同,如何找到top K的IP?如何直接用Linux系统命令实现?
解题思路:前半部分的处理和上题一样,后半部分处理不同的是,我们先建立一个堆(注意要建立小堆)。每个文件寻找出前K个出现次数较多的IP,1000分文件都找出前K个次数较多的IP,最后1000K个IP中在继续小堆查找判断,最后还是能找出前K个次数出现较多的IP
(3)给定100亿个整数,设计一个算法找到只出现一次的整数。
解题思路:整数一共有42亿多个,100亿个数中一定有重复的数字。
1M = 1024K = 2^10K
1K = 1024B = 2^10B
1B = 1024b = 2^10b
故:1G = 2^10M
= 2^10 * 2^10B
= 2^10 * 2^10 * 2^10b
如果一个整数占用一个字节,那么1G的内存可以处理约10亿的整数,一共有42亿多个无重复的整数,那么就需要4G的内存。1byte = 8位,每个位判断该数字存在与不存在,那么就需要4G/8 = 512M的内存,内存占用率大大降低,提高了效率。
然而,一个位只能表示这个数存在与否,不能断定这个数出现了几次。这个时候,我们应该考虑用两个位来存放一个数的状态。00表示这个数出现了0次,01表示这个数出现了1次,10表示这个数出现了多次,11状态我们暂且不用。最后,我们找出状态是01的数就可以了。
那么,这样占多少内存呢?一个位处理42亿多个整数占用了512M的内存,那么两个位处理42亿多个整数占用了1G的内存。如果这个时候,考官还想你500M左右处理这道题呢?那么,我们可以考虑正整数和负整数分开处理,也可以达到考官的要求。
(4)给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件的交集?
解题思路:给定1000个小文件,每个小文件都编号。对A,B两个大文件的100亿个数切分,每个数对1000取余,余数为几就放在编号为几的文件中。最后比较的时候,我们只取编号相同的小文件去比较。(将100亿个数分到1000个小文件中,每个文件大小512M,每次取A,B文件进行比较,两个文件刚好1G,符合题意)
(5)一个文件有100亿个int,1G内存,设计算法找出出现次数不超过2次的所有整数。
解题思路:这道题和第3题的解题思路是一样的,也是设置两个位来存放一个数的状态,00表示不存在,01表示出现一次,10表示出现两次,11表示出现多次。这时候我们只有知道状态为01或者10的数就可以了。两个位表示所需要占用的内存为1G(计算过程参考第三题)
(6)给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?给出精确算法和近似算法。
解题思路:
精确算法:同第四题的思路相同
近似算法:布隆过滤器
<strong><span style="font-size:18