布隆過濾器 - URL去重,字符串去重



  布隆過濾器用於字符串去重復,比如網絡爬蟲抓取時URL去重、郵件提供商反垃圾黑名單Email地址去重。等等。用哈希表也可以用於元素去重,但是占用空間比較大,而且空間使用率只有50%。
  布隆過濾器只占哈希表的1/8或1/4的空間復雜度,就能解決同樣的問題,但是有一定的誤判,而且不能刪除已有元素。元素越多,誤報率越大,但是不會漏報。對於還需要刪除的布隆過濾器,還有Counter Bloom Filter,這個是布隆過濾器的變體,可以刪除元素。

布隆過濾器的原理

布隆過濾器需要的是一個位數組(和位圖類似)和K個映射函數(和Hash表類似),在初始狀態時,對於長度為m的位數組array,它的所有位被置0。

  

對於有n個元素的集合S={S1,S2...Sn},通過k個映射函數{f1,f2,......fk},將集合S中的每個元素Sj(1<=j<=n)映射為K個值{g1,g2...gk},然后再將位數組array中相對應的array[g1],array[g2]......array[gk]置為1:

  

  如果要查找某個元素item是否在S中,則通過映射函數{f1,f2,...fk}得到k個值{g1,g2...gk},然后再判斷array[g1],array[g2]...array[gk]是否都為1,若全為1,則item在S中,否則item不在S中。這個就是布隆過濾器的實現原理。
前面說到過,布隆過濾器會造成一定的誤判,因為集合中的若干個元素通過映射之后得到的數值恰巧包括g1,g2,...gk,在這種情況下可能會造成誤判,但是概率很小。
  總結一下,感覺布隆過濾器的實現原理並不是太復雜,但是映射函數這個東西說的還是比較虛無。對於布隆過濾器的數學證明,數學公式之類的,我還是覺得我研究不了那么深入了。畢竟現階段水平還不到有時間去研究這么底層的,甚至於底層到和數學打交道的東西,就現階段來說,只要知道有這樣一個東西可用,會用,我就很滿足了。

  本來此處留空是准備自己寫個簡易版的布隆過濾器的,但是實在不懂,看來數據結構還遠遠有待補充。

  另外附上一個第三方布隆過濾器控件,地址如下:http://bloomfilter.codeplex.com/

  DEMO:

    class Program
    {
        static void Main(string[] args)
        {
            //聲明一個布隆過濾器的初始容量包含10000個項目
            int capacity = 10000;
            float errorRate = 0.0001F;
            //初始化一個布隆過濾器
            Filter<string> urlSeen = new Filter<string>(capacity, errorRate, null);
            //添加數據進入布隆過濾器
            urlSeen.Add("www.baidu.com");
            urlSeen.Add("www.google.com");
            urlSeen.Add("www.qq.com");
            Console.WriteLine("請輸入網址:");
            string str = Console.ReadLine();
            //測試布隆過濾器是否記得這個url
            if (urlSeen.Contains(str))
            {
                Console.WriteLine("此url已經有了!");
            }
            else
            {
                Console.WriteLine("此url尚未被收錄!");
            }

            Console.ReadKey();
        }
    }

  測試如下:

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM