海量数据

倒排索引算法

    经过关键词找内容:key->value,value是找到的全部内容的索引链表或者是树,按照批评度排列数组

 

Trie树   (前缀索引)数据结构

    字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不只限于字符串),因此常常被搜索引擎系统用于文本词频统计。它的优势是:最大限度地减小无谓的字符串比较,查询效率比哈希表高。函数

    再海量数据查找过程当中,时间复杂度与海量数据无关,只与查找数据长度有关可视为O(1)搜索引擎

    Trie的核心思想是空间换时间。利用字符串的公共前缀来下降查询时间的开销以达到提升效率的目的。 url

经过双数组表示法能够简化空间复杂度 spa

 

Bloom Filter.net

    用一个大数组保存0/1,用几个hash函数处理存储的数据。日志

    如何选择数组长度和hash函数次数是须要提早预算的。blog

 

Skip List 跳表

    实现简单(相比红黑树),时间复杂度O(lgn), 适合并行计算(红黑树不适合)

 

MD5, 判断惟一性,防修改等

 

如何有效合并两个文件:一个是1亿条的用户基本信息,另外一个是用户天天看电影连续剧等的记录,5000万条。其中内存只有1G。

显然内存不能同时存下全部的数据,因此考虑分而治之的思想。
假设1K Byte能够保存一个用户的基本信息和看电影记录。咱们能够将基本信息和看电影记录都按照hash(user_name)%100的余数各分红100个小文件。利用1G内存,咱们能够每次只处理一对小文件,而后将结果输出到一个文件中便可。
在处理一对小文件时,能够利用key为用户名的hash_map将基本信息和看电影记录合并在一块儿。

 

 

有1到10w这10w个数,去除2个并打乱次序,如何找出那两个数?

方法1:

申请10w个bit的空间,每一个bit表明一个数字是否出现过。
开始时将这10w个bit都初始化为0,表示全部数字都没有出现过。
而后依次读入已经打乱循序的数字,并将对应的bit设为1。
当处理完全部数字后,根据为0的bit得出没有出现的数字。

方法2:

首先计算1到10w的和,平方和。
而后计算给定数字的和,平方和。
两次的到的数字相减,能够获得这两个数字的和,平方和。
因此咱们有
x + y = n
x^2 + y^2 = m
解方程能够获得x和y的值。

 

给定a、b两个文件,各存放50亿个url,每一个url各占用64字节,内存限制是4G,如何找出a、b文件共同的url?

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

https://my.oschina.net/u/3705388/blog/1612961

 

在100w个数中找最大的前100个数

应该使用某种数据结构保存迄今最大的100个数。每读到一个新数时,将新数和保存的100个数中的最小一个相比较,若是新数更大些,则替换。这样扫描一遍100w个数也就得到了最大的100个数。
对于保存的100个数的数据结构,应该在最小复杂度的条件下知足
1)能够得到最小的数;
2)将最小数替换为另外一个数后能够从新调整,使其能够知足条件1。
可见小根堆能够知足这些条件。
因此应该采用小根堆+扫描的方法。

 

在一个文件中有 10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。

不妨假设10G个整数是64bit的。
2G内存能够存放256M个64bit整数。
咱们能够将64bit的整数空间平均分红256M个取值范围,用2G的内存对每一个取值范围内出现整数个数进行统计。这样遍历一边10G整数后,咱们便知道中数在那个范围内出现,以及这个范围内总共出现了多少个整数。
若是中数所在范围出现的整数比较少,咱们就能够对这个范围内的整数进行排序,找到中数。若是这个范围内出现的整数比较多,咱们还能够采用一样的方法将此范围再次分红多个更小的范围(256M=2^28,因此最多须要3次就能够将此范围缩小到1,也就找到了中数)。

 

求一个论坛的在线人数,假设有一个论坛,其注册ID有两亿个,每一个ID从登录到退出会向一个日志文件中记下登录时间和退出时间,要求写一个算法统计一天中论坛的用户在线分布,取样粒度为秒。

一天总共有 3600*24 = 86400秒。
定义一个长度为86400的整数数组int delta[86400],每一个整数对应这一秒的人数变化值,可能为正也可能为负。开始时将数组元素都初始化为0。
而后依次读入每一个用户的登陆时间和退出时间,将与登陆时间对应的整数值加1,将与退出时间对应的整数值减1。
这样处理一遍后数组中存储了每秒中的人数变化状况。
定义另一个长度为86400的整数数组int online_num[86400],每一个整数对应这一秒的论坛在线人数。
假设一天开始时论坛在线人数为0,则第1秒的人数online_num[0] = delta[0]。第n+1秒的人数online_num[n] = online_num[n-1] + delta[n]。
这样咱们就得到了一天中任意时间的在线人数。

 

 

给定一个单词a,若是经过交换单词中字母的顺序能够获得另外的单词b,那么定义b是a的兄弟单词。如今给定一个字典,用户输入一个单词,如何根据字典找出这个单词有多少个兄弟单词? 使用hash_map和链表。  首先定义一个key,使得兄弟单词有相同的key,不是兄弟的单词有不一样的key。例如,将单词按字母从小到大从新排序后做为其key,好比bad的key为abd,good的key为dgoo。  使用链表将全部兄弟单词串在一块儿,hash_map的key为单词的key,value为链表的起始地址。  开始时,先遍历字典,将每一个单词都按照key加入到对应的链表当中。当须要找兄弟单词时,只需求取这个单词的key,而后到hash_map中找到对应的链表便可。  这样建立hash_map时时间复杂度为O(n),查找兄弟单词时时间复杂度是O(1)。

相关文章
相关标签/搜索