BAT面試題——URL查重及布隆過濾器Bloom

BAT面試題——URL查重

問題描述:
給你A、B兩個文件,各存放50億條URL,每條URL佔用64字節,內存限制是16G,讓你找出A、B文件共同的URL。

常規的解決辦法

也是最容易想到的,就是對於文件A,讀入內存。對於文件B中的每一個元素,判斷是否在A中出現過。
我們來分析一下這樣做的空間和時間複雜度:第一步,讀入文件到內存,需要的內存是50(108)64=320G50*(10**8)*64 = 320G ,顯然我們在實際中沒有那麼大的內存。

另外,通過遍歷A文件和B文件中的每一個元素,需要的時間複雜度是o(MN)o(M*N),M、N是兩個文件元素的大小,時間複雜度是(5050)(50億*50億)

布隆過濾器

基本思路:

Bloom過濾器

  1. 設數據集合A={a1,a2,,an}A = \lbrace a_1, a_2, ……, a_n \rbrace ,含n個元素,作爲待操作的集合。
  2. Bloom Filter用一個長度爲m的位向量V(Bit Array),表示集合中的元素,位向量初始值全爲0。
  3. k個具有均勻分佈特性的散列函數h1h2hkh_1,h_2,……,h_k
  4. 對於要加入的元素,首先經過k個散列函數產生k個隨機數r1r2rkr_1,r_2,……,r_k ,使向量V的相應位置(b1b2bkb_1,b_2,……,b_k)均置爲1。集合中其他元素也通過類似的操作,將向量V的若干位置爲1。
  5. 對於新要加入的元素進行檢查,首先將該元素經過上步中類似操作,獲得k個隨機數r1r2rkr_1,r_2,……,r_k ,然後查看向量V的相應位置b1b2bkb_1,b_2,……,b_k上的值,若全爲1,則該元素已經在之前的集合中,爲舊元素;若至少有一個0存在,表明此元素不在之前的集合中,爲新元素。

算法特點:

返回頂部
對於已經在集合中的元素,通過5中的查找方法,一定可以判定該元素在集合中;
對於不在集合中的元素,可能會被誤判在集合中。

原因:

hash函數的特點是,對於相同的字符串,經過hash函數處理後,結果必然相同;
而不同的字符串,經過hash函數處理後,結果可能相同(概率很小)。

過程:

對於A中50億個文件,我們使用一個誤報率爲1%的bloom過濾器,每個元素需要使用9.6bits,總計需要(50(1089.6)bits=6G(50*(10**8)*9.6)bits = 6G,在內存的使用上,是符合我們要求的,然後對於使用A文件建立的bloom過濾器,我們遍歷B中的每一個元素,判斷是否在A中出現過。

from pybloom_live import BloomFilter  # 也可以from pybloom import BloomFilter
# 生成一個容量爲50億個元素,錯誤率爲1%的bloom過濾器
bloom_A_file =  BloomFilter(capacity = 5000000000, error_rate=0.01)
# 至少保持電腦的可用內存在8G以上


with open(file_A) as f1:              # 遍歷A文件中的每一個元素,加入到bloom過濾器中
    for sel in f1:
        bloom_A_file.add(sel)
        
with open(file_B) as f2:              # 遍歷B文件,找出在A文件中出現的元素,並打印出來
    for sel in f2:
        if sel in bloom_A_file:
            print(sel)

總結

hash函數和布隆過濾器的特點:
相同的字符串,處理後結果一定相同
不同的字符串,處理後結果可能相同
返回頂部

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章