给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件共同的url?
給定a、b兩個(gè)文件,各存放50億個(gè)url,每個(gè)url各占64字節(jié),內(nèi)存限制是4G,讓你找出a、b文件共同的url?
兩種方法:
一、采用Bloom filter,假設(shè)布隆過濾器的錯(cuò)誤率為0.01,則位數(shù)組大小m約為輸入元素個(gè)數(shù)n的13倍,此時(shí)需要的哈希函數(shù)k約為8個(gè)。
元素個(gè)數(shù):n = 5G
位數(shù)組大小:m = 5G * 13 = 65G = 650億 即需要650億個(gè)bit位才能達(dá)到錯(cuò)誤率0.01
而我們擁有的內(nèi)存可容納bit位個(gè)數(shù):4G * 8bit = 32G bit = 320億,按此實(shí)現(xiàn)錯(cuò)誤率大于0.01。
布隆過濾器:https://blog.csdn.net/qq_41946557/article/details/102593912
二、采用分治的思想
假如每個(gè)url大小為10bytes,那么可以估計(jì)每個(gè)文件的大小為50G×64=320G,遠(yuǎn)遠(yuǎn)大于內(nèi)存限制的4G,所以不可能將其完全加載到內(nèi)存中處理,可以采用分治的思想來解決。
Step1:遍歷文件a,對(duì)每個(gè)url求取hash(url)%1000,然后根據(jù)所取得的值將url分別存儲(chǔ)到1000個(gè)小文件(記為a0,a1,...,a999,每個(gè)小文件約300M);
Step2:遍歷文件b,采取和a相同的方式將url分別存儲(chǔ)到1000個(gè)小文件(記為b0,b1,...,b999);
巧妙之處:這樣處理后,所有可能相同的url都被保存在對(duì)應(yīng)的小文件(a0vsb0,a1vsb1,...,a999vsb999)中,不對(duì)應(yīng)的小文件不可能有相同的url。然后我們只要求出這個(gè)1000對(duì)小文件中相同的url即可。
Step3:求每對(duì)小文件ai和bi中相同的url時(shí),可以把a(bǔ)i的url存儲(chǔ)到hash_set/hash_map中。然后遍歷bi的每個(gè)url,看其是否在剛才構(gòu)建的hash_set中,如果是,那么就是共同的url,存到文件里面就可以了。
【補(bǔ)充】
1、為什么使用hash?是把任意長度的輸入(又叫做預(yù)映射pre-image)通過散列算法變換成固定長度的輸出,該輸出就是散列值。這種轉(zhuǎn)換是一種壓縮映射,也就是,散列值的空間通常遠(yuǎn)小于輸入的空間,不同的輸入可能會(huì)散列成相同的輸出,所以不可能從散列值來確定唯一的輸入值。簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數(shù)。
也就是說將url通過hash函數(shù)變成一個(gè)固定長度的值,(url有的挺長的!)然后假如有一部分?jǐn)?shù)值%1000后,等于0,那么放入到a0中,等于1的放入到a1中,以此類推。。。
【注】:
-
1、Hash取模是一種等價(jià)映射,不會(huì)存在同一個(gè)元素分散到不同小文件中的情況,即這里采用的是mod1000算法,那么相同的url在hash取模后,只可能落在同一個(gè)文件中,不可能被分散的。因?yàn)槿绻麅蓚€(gè)url相等,那么經(jīng)過Hash(url)之后的哈希值是相同的,將此哈希值取模(如模1000),必定仍然相等。
-
2、那到底什么是hash映射呢?簡單來說,就是為了便于計(jì)算機(jī)在有限的內(nèi)存中處理big數(shù)據(jù),從而通過一種映射散列的方式讓數(shù)據(jù)均勻分布在對(duì)應(yīng)的內(nèi)存位置(如大數(shù)據(jù)通過取余的方式映射成小樹存放在內(nèi)存中,或大文件映射成多個(gè)小文件),而這個(gè)映射散列方式便是我們通常所說的hash函數(shù),設(shè)計(jì)的好的hash函數(shù)能讓數(shù)據(jù)均勻分布而減少?zèng)_突。盡管數(shù)據(jù)映射到了另外一些不同的位置,但數(shù)據(jù)還是原來的數(shù)據(jù),只是代替和表示這些原始數(shù)據(jù)的形式發(fā)生了變化而已。
mini版代碼實(shí)現(xiàn):https://blog.csdn.net/qq_41946557/article/details/102711573?
?
總結(jié)
以上是生活随笔為你收集整理的给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件共同的url?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 练习:每一分钟产生一个文件,保存本分钟内
- 下一篇: 代码实现【mini版】——给定a、b两个