演算法學習,演算法學習網站

來源:互聯網
上載者:User

演算法學習,演算法學習網站

  • Bloom filter簡介
  • Bloom Filter計算方法
  • Bloom Filter優點缺點
    • 優點
    • 缺點
  • 圖示說明

Bloom filter簡介

Bloom filter 是由 Howard Bloom 在 1970 年提出的二進位向量資料結構,它具有很好的空間和時間效率,被用來檢測一個元素是不是集合中的一個成員。如果檢測結果為是,該元素不一定在集合中;但如果檢測結果為否,該元素一定不在集合中。因此Bloom filter具有100%的召回率。這樣每個檢測請求返回有“在集合內(可能錯誤)”和“不在集合內(絕對不在集合內)”兩種情況,可見 Bloom filter 是犧牲了正確率和時間以節省空間的。

以上文字來源百度百科

Bloom Filter計算方法

如需要判斷一個元素是不是在一個集合中,我們通常做法是把所有元素儲存下來,然後通過比較知道它是不是在集合內,鏈表、樹都是基於這種思路,當集合內元素個數的變大,我們需要的空間和時間都線性變大,檢索速度也越來越慢。 Bloom filter 採用的是雜湊函數的方法,將一個元素映射到一個 m 長度的陣列上的一個點,當這個點是 1 時,那麼這個元素在集合內,反之則不在集合內。這個方法的缺點就是當檢測的元素很多的時候可能有衝突,解決方案就是使用 k 個雜湊 函數對應 k 個點,如果所有點都是 1 的話,那麼元素在集合內,如果有 0 的話,元素則不在集合內。

Bloom Filter優點缺點優點
  • 插入時間和查詢時間都是常數。
  • 儲存的不是資料本身,安全性好。
缺點
  • 插入的元素越多,錯判性越大。
  • 不能刪除元素。
圖示說明

例如我們有一個簡單的Bloom Filter結構如下:(所有位都是0)

      [ 0 0 0 0 0 0 0 0 0 0 ]

第一次插入a用兩個雜湊函數,映射到1 4位置上,變為1.

      [ 1 0 0 1 0 0 0 0 0 0 ]

第二次插入b同樣的hash函數,映射到1 8位置上, 變為1.

      [ 1 0 0 1 0 0 0 1 0 0 ]

這樣就存放了a b兩個元素,當我們尋找a是否在的時候,兩次hash找到1 4位置,發現同時為 1。則表明a存在。

但是假如我們尋找的d雜湊後映射到4 8位置,發現也同時為 1. 認為存在,這就出錯了,因為現在裡面只存放了a b沒有d

下面寫下我用C++寫的代碼實現,比較簡單的實現了下,具體的Hash演算法我都簡略的寫了。

首先是標頭檔Header.h

////  Header.h//  BloomFilter////  Created by Alps on 15/3/19.//  Copyright (c) 2015年 chen. All rights reserved.//#ifndef BloomFilter_Header_h#define BloomFilter_Header_hclass BitMap{public:    BitMap(){        bitmap = NULL;        size = 0;    }    BitMap(int size){        bitmap = NULL;        bitmap = new char[size];        if (bitmap == NULL) {            printf("ErroR In BitMap Constractor!\n");        }else{            memset(bitmap, 0x0, size * sizeof(char));            this->size = size;        }    }    int initBitMap(int size){        bitmap = NULL;        bitmap = new char[size];        if (bitmap == NULL) {            printf("ErroR In BitMap Constractor!\n");            return 0;        }else{            memset(bitmap, 0x0, size * sizeof(char));            this->size = size;            return this->size;        }    }    /*     * set the index bit to 1;     */    int bitmapSet(int index){        int addr = index/8;        int addroffset = index%8;        unsigned char temp = 0x1 << addroffset;        if (addr > (size+1)) {            return 0;        }else{            bitmap[addr] |= temp;            return 1;        }    }    /*     * return if the index in bitmap is 1;     */    int bitmapGet(int index){        int addr = index/8;        int addroffset = index%8;        unsigned char temp = 0x1 << addroffset;        if (addr > (size + 1)) {            return 0;        }else{            return (bitmap[addr] & temp) > 0 ? 1 : 0;        }    }    /*     * del the index from 1 to 0     */    int bitmapDel(int index){        if (bitmapGet(index) == 0) {            return 0;        }        int addr = index/8;        int addroffset = index%8;        unsigned char temp = 0x1 << addroffset;        if (addr > (size + 1)) {            return 0;        }else{            bitmap[addr] ^= temp;            return 1;        }    }private:    char *bitmap;    int size;};#endif

標頭檔儲存好,放到工程路徑下。
下面是BloomFilter.cpp檔案了。

////  main.cpp//  BloomFilter////  Created by Alps on 15/3/18.//  Copyright (c) 2015年 chen. All rights reserved.//#include <iostream>#include "Header.h"using namespace std;template <class Type> class BloomFilter{public:    BloomFilter();    BloomFilter(int length){        bitmap.initBitMap(length);        this->length = length;    }    bool Add(const Type &T);    bool Contains(const Type &T);    int HasH(const Type &T);private:    BitMap bitmap;    int length;};template <class Type> int BloomFilter<Type>::HasH(const Type &T){    int temp = (int) T;    return temp%length;}template <class Type> bool BloomFilter<Type>::Add(const Type &T){    int first = HasH(T);    int second = HasH(first);    if (bitmap.bitmapSet(first) && bitmap.bitmapSet(second)) {        return true;    }else{        return false;    }}template <class Type> bool BloomFilter<Type>::Contains(const Type &T){    int first = HasH(T);    int second = HasH(first);    if (bitmap.bitmapGet(first) && bitmap.bitmapGet(second)) {        return true;    }else{        return false;    }}int main(int argc, const char * argv[]) {    BloomFilter<int> bloom(10);    bloom.Add(3);    if (bloom.Contains(3)) {        printf("true\n");    }else{        printf("false\n");    }    if (bloom.Contains(2)) {        printf("true\n");    }else{        printf("false\n");    }    return 0;}

這就是My Code了。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.