1. 程式人生 > >雜湊擴充套件——布隆過濾器

雜湊擴充套件——布隆過濾器

一、基本原理:

     對於原理來說很簡單,位陣列+k個獨立hash函式。將hash函式對應的值的位陣列置1,查詢時如果發現所有hash函式對應位都是1說明存在,但是這個過程並不能保證查詢的結果是100%正確的。

二、要點:

  1. 刪除
         不支援刪除一個已經插入的關鍵字,因為該關鍵字對應的位可能會牽動到其他的關鍵字。所以一個簡單的改進就是用一個counter陣列代替位陣列,就可以支援刪除了。
  2. 誤判
         Bloom Filter是一種空間效率很高的隨機資料結構,它利用位陣列很簡潔地表示一個集合,並能判斷一個元素是否屬於這個集合。但是這種高效是有一定代價的:在判斷一個元素是否屬於某個集合時,有可能會把不屬於這個集合的元素誤認為屬於這個集合
    。因此,Bloom Filter不適合那些“零錯誤”的應用場合,而在能容忍低錯誤率的應用場合下,Bloom Filter通過極少的錯誤換取了儲存空間的極大節省。

三、程式碼實現:

  • BloomFilter.h
#ifndef __BLOOMFILTER_H__
#define __BLOOMFILTER_H__

#include "Bitmap.h"

typedef const char* BFKeyType;

typedef struct BloomFilter
{
    BitMap _bm;
}BloomFilter;

void BloomFilterInit(BloomFilter* bf, size_t range);
void
BloomFilterSet(BloomFilter* bf, BFKeyType key); int BloomFilterTest(BloomFilter* bf, BFKeyType key); void BloomFilterDestory(BloomFilter* bf); #endif __BLOOMFILTER_H__
  • BloomFilter.c
#define _CRT_SECURE_NO_WARNINGS 1

#include "BloomFilter.h"

//初始化
void BloomFilterInit(BloomFilter* bf, size_t range)
{
    assert(bf);
    BitMapInit(&(bf->_bm), range*5
); } //字串雜湊演算法 size_t BFHashFunc1(BFKeyType str) { register size_t hash = 0; while (*str) { hash = hash * 131 + (*str++); } return hash; } size_t BFHashFunc2(BFKeyType str) { register size_t hash = 0; size_t magic = 63689; while (*str) { hash = hash * magic + (*str++); magic *= 378551; } return hash; } size_t BFHashFunc3(BFKeyType str) { register size_t hash = 0; while (*str) { hash = 65599 * hash + (*str++); } return hash; } //將x所在的位置置為1 void BloomFilterSet(BloomFilter* bf, BFKeyType key) { assert(bf); size_t hash1 = BFHashFunc1(key) % bf->_bm._range; BitMapSet(&bf->_bm, hash1); size_t hash2 = BFHashFunc2(key) % bf->_bm._range; BitMapSet(&bf->_bm, hash2); size_t hash3 = BFHashFunc3(key) % bf->_bm._range; BitMapSet(&bf->_bm, hash3); } //檢測x是否存在 int BloomFilterTest(BloomFilter* bf, BFKeyType key) { assert(bf); size_t hash1 = BFHashFunc1(key) % bf->_bm._range; if (BitMapTest(&bf->_bm, hash1) == 0) { return 0; } size_t hash2 = BFHashFunc2(key) % bf->_bm._range; if (BitMapTest(&bf->_bm, hash2) == 0) { return 0; } size_t hash3 = BFHashFunc3(key) % bf->_bm._range; if (BitMapTest(&bf->_bm, hash3) == 0) { return 0; } return 1; } //銷燬 void BloomFilterDestory(BloomFilter* bf) { assert(bf); BitMapDestroy(&bf->_bm); }
  • Test.c
#define _CRT_SECURE_NO_WARNINGS 1

#include "BloomFilter.h"

int main()
{
    BloomFilter bf;
    BloomFilterInit(&bf, 10);

    BloomFilterSet(&bf, "a");
    BloomFilterSet(&bf, "ab");
    BloomFilterSet(&bf, "abc");

    printf("%d\n", BloomFilterTest(&bf, "a"));
    printf("%d\n", BloomFilterTest(&bf, "ab"));
    printf("%d\n", BloomFilterTest(&bf, "abc"));
    printf("%d\n", BloomFilterTest(&bf, "abcd"));

    BloomFilterDestory(&bf);

    system("pause");
    return 0;
}

部分標頭檔案和函式引用請參照雜湊變形—點陣圖