1)给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址?
初步分析:
100G普通机器内存中肯定是放不下的,目前使用的IP地址相当于一个32位的字符串,所以我们考虑切分,假设有1G可用内存我们切分为100份,那我们需要把这100个文件全部遍历,每一次出现的IP地址进行统计,最后找出出现次数最多的IP地址,此办法可行但是效率不高。
优化:
把这32位的IP地址通过字符串哈希函数转化为对应的整形,模除1000后将文件分为1000份:从硬盘中读取这些IP,转化为整形后对文件个数取余,余数是多少就放进哪个文件,这样就保证了同一个ip地址在同一个文件里。这种方法叫做哈希分桶法(不均匀)。分好之后去统计每个文件里出现次数最多的IP地址,再转化为找1000个IP出现次数最多的一个。
2)与上题条件相同,如何找到top K的IP?如何直接用Linux系统命令实现?
初步分析:继上题可能很容易想到找出每个文件中出现次数最多的,在它们中再找出topK个,可是你怎么能保证一个文件中出现最多的次数就一定比另一个文件中出现最少的次数大。所以这种思路有问题。
优化:首先和第一题一样,先采用哈希分桶分好1000个文件,然后找出每个文件的Topk(在这里用优先级队列或者建小堆都可以),最后Topk进行汇总。
3)给定100亿个整数,设计算法找到只出现一次的整数!
初步分析:
普通机器100亿个整数内存肯定是放不下的,整数范围是42亿多,所以这100亿整数中肯定有重复的,可能首先想到的是切分,切分到内存中可以放下为止,然后再去遍历寻找,无这种方法效率太低。
优化:用两位位图来解决,00代表不存在,01代表出现一次,10代表出现2次,11代表出现多次。用两个位来表示一个数,42亿byte = 4G ;1byte = 8位;现在只需要84亿位,大约需要1个G.
4)给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集!
依然用到哈希分桶法:100亿个整数分到1000个文件里,余数为几就放到编号为几的文件中。最后比较的时候只取编号相同的小文件去比较即可,因为哈希分桶保证了大小相同的整数一定分到了同一个文件中。(将100亿个数分到1000个小文件中,每个文件大小512M,每次取A,B文件进行比较,两个文件刚好1G)
5)1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数!
类似于第三题,依然使用两位位图,这次我们关注的是01和10状态。
6)给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?分别给出精确 算法和近似算法!
近似算法:布隆过滤器因为存在误判(存在不一定准确,不存在一定准确)。
精确算法:同(4)。
7)如何扩展BloomFilter使得它支持删除元素的操作?
首先要明白为什么布隆不支持删除操作,因为一个字符串是用多个位表示的,其它字符串很可能会与要删除的字符串占用了相同的位,所以不能直接删除。
解决:
采用引用计数,如果字符串出现的次数可能比较大,一个char是不行的,得用size_t,但是这样就
失去了布隆过滤器节省空间的优势。若采用引用计数就不用再拿一个位来表示不存在了,直接用引用计数为0就可以代表不存在。
8)给上千个文件,每个文件大小为1K—100M。给n个词,设计算法对每个词找到所有包含它的文件,你只有100K内存!
9)有一个词典,包含N个英文单词,现在任意给一个字符串,设计算法找出包含这个字符串的所 有英文单词!
解决此类问题我们要用到一种特殊的数据结构叫”字典树“。
字典树:一种树形结构,典型应用是用于统计,排序和保存大量的字符串,所以经常被搜索引擎系统用于文本词频统计。
特点:(1)利用串的公共前缀,节约内存。
(2)根节不包含任何字母
(3)其余节点仅包含一个字母。
具体实现:
(1)从根节点开始一次搜索;
(2)取得要查找的关键字的第一个字母,并根据字母选择对应的子树,接下来转到该子树继续对第二个字母进行检索。
(3)迭代过程
(4)在某一节点处。最后一个字母已经找到,则读取附在该节点上的信息,即完成查找。
其余方法:
(1)暴力求解:使用strstr()进行字符串匹配
(2)倒排索引
来源:CSDN
作者:德卡拉
链接:https://blog.csdn.net/zjx624bjh/article/details/80251282