1、布隆过滤器用于集合的建立与查询,并可以节省大量空间
2、一致性哈希解决数据服务器负载管理问题
3、利用并查集结构做岛问题的并行计算
4、哈希函数可以把数据按照种类均匀分流
5、位图解决某一范围上数字的出现情况,并可以节省大量空间
6、利用分段统计思想,并进一步节省大量空间
7、利用堆、外排序来做多个处理单元的结果合并
32为无符号整数的范围是0~4294967295,现在有一个正好包含40亿个无符号整数的文件,可以使用最多1GB的内存,怎么找到出现次数最多的数?
排序?不行,内存只有1G,无法在内存排序
1、假设1G内存,使用hash表最多只能装下1千万条记录,那么40亿除以1千万,等于400,准备400个文件
2、然后每一个数,通过hash函数,算出一个hash值,模400,得到一个文件编号,该数发送到对应文件
3、此时同一个数字,只会进入一个文件,文件里面存的是该数字出现的次数
4、这样就搞成了400个文件,此时每次加载一个文件,遍历文件的每条记录,抓出出现次数最多的
5、最后这400个出现次数最多的数PK一下,得出整体出现次数最多的数。
6、如果发现一个文件大小过大,在内存还是装不下,那么文件就搞500个、600个…
如果题目要求返回出现次数最多的所有数,那么就拿着这个次数,到每个文件中再找一遍,看有没有出现这么多次的数,有的话就全部抓出来,返回。
题目二32位无符号整数的范围是0~4294967295,
现在有一个正好包含40亿个无符号整数的文件,
所以在整个范围中必然存在没出现过的数。
可以使用最多1GB的内存,怎么找到所有没有出现过的数?
set去重统计?不行,内存会爆掉。
使用位图,8个bit才一个直接,那么就准备4294967295bit长度的位图进行统计。
如果实现bit数组?使用基础类型拼,长度为10的int数组,等于320bit长度的bit数组,第i个bit就是arr[i / 32]这个数的第i%32位
那么这一位代表的数是否存在,就这样计算:
int status = arr[i / 32] & (1<< (i%32)) != 0 ? 1 : 0;
如果status是1,那么就是存在,0就是不存在。
【进阶】
内存限制3KB,但是只用找到以没出现过的数即可。
3KB大约能存下750个整形,那么准备一个离750最近的2的某次方,得到512,那么申请512长度的数组
此时可以把0~4294967295均分为512份(512个文件),每一份负责负责的范围的长度是8388608
这样,肯定在每个范围上存储数不满8388608的情况,找到这个不满的范围,再分512份,再找不满的小范围,再分512份…,几次过后就能找到没出现过的1个数。
【进阶】
内存中只能申请有限几个遍历,但是只用找到以没出现过的数即可。
申请两个遍历L和R,对0~4294967295进行二分(两个文件)
统计两边出现的数的个数
其中有一边肯定不满,再对不满的一边进行二分,还是用两个变量L、R统计两边范围出现的数的个数
如此不断二分,最终会找到没出现过的1个数
有一个包含100亿个URL的大文件,假设每个URL占用64B,
请找出其中所有重复的URL
如果允许失误率,使用布隆过滤器
如果不允许,使用hash分流,分到不同小文件,看小文件是否有重复的。
【补充】
某搜索公司一天的用户搜索词汇是海量的(百亿数据量),
请设计一种求出每天人们Top100词汇的可行办法。
32为无符号整数的范围是0~4294967295,
现在有40亿个无符号整数,
可以使用最多1GB内存,
找出所有出现了两次的数。
用两个bit位表示一个数出现的次数,比如那0bit为何1bit为表示0这个数出现的次数,00表示出现0次,01表示出现1次,10,表示出现两次,11表示出现3次或以上。
这样1个byte表示4个数。
但是4294967295除以4,超过了1G,那就继续用上面分段统计的办法。
也就是:位图 + 分段统计,先统计前面一半(0~2^31)出现两次的数,在统计后面一半的
32位无符号整数的范围是0~4294967295,
现在有40亿个无符号整数
可以使用最多3KB的内存,怎么找到这40亿个整数的中位数?
bfprt?不行,内存会爆掉。
3KB大约能存下750个整形,那么准备一个离750最近的2的某次方,得到512,那么申请512长度的数组arr。
此时可以把0~4294967295均分为512份(512个文件),每一份负责负责的范围的长度是8388608。
数组arr中每一个数统计自己范围内出现的数的个数。
中位数是第20亿个数,那么看数组arr累加到大于等于20亿,是数组arr中的第几个数。
假设arr[129]冲动了20亿,那么中位数一定在第129号文件。
然后以相同的方法,对129号文件分512份,数组arr统计每一份中出现的数的个数…循环往复,最终找到中位数。
32位无符号整数的范围是0~4294967295,
有一个10G大小的文件,每一行都装着这种类型的数字,
整个文件是无序的,给你5G的空间,
请你输出一个10G大小的文件,就是原文件所有数字排序的结果。
现在不看5G内存,假设内存严重不足,只能存几条记录
那么准备一个堆,大根堆,只存3条记录,存的是数字和出现的次数
申请1个10G的文件,用于存放结果
遍历文件,在堆中记录数字以及该数出现的次数:
假设遍历到3,记录 3 =>1,表示3出现1次
再遍历到3,记录 3 =>2,表示3出现2次
遍历到9,记录 9 =>1
遍历到7,记录 7 =>1
遍历到8,堆满了,弹出 9 =>1,记录8 =>1
遍历到6,堆满了,弹出 8 =>1,记录6 =>1
…
文件遍历完了,堆中就记录了整个文件中前3小的数,出现的次数
假设是
1 =>1000
3 =>2000
5 =>1000
然后在10G的文件中,数字1写1000次,数字3写2000次,数字5写1000次
然后用1个遍历记录5,表示上一次遍历到的大的数
再搞一遍这个遍历,在堆中记录数字以及该数出现的次数,但是小于等于5的数字不再记录
…
这样一直搞,直至所有的数都统计完(某一次循环,堆没放满),10G排序号的文件返回。
一个大文件,返回里面出现的数的前100名。
解法:分成不同的小文件,通过hash分流把数字分发到不同文件,每个文件统计Top100,然后在内存做归并排序。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
售后响应及时
7×24小时客服热线数据备份
更安全、更高效、更稳定价格公道精准
项目经理精准报价不弄虚作假合作无风险
重合同讲信誉,无效全额退款