C 中布隆過濾器詳解

2021-10-03 15:01:10 字數 3028 閱讀 6195

**

布隆過濾器:

它實際上就是乙個雜湊和點陣圖的結合,因為點陣圖是一種精確查詢的結構,因為它要把所有可能出現的數字都列舉出來,但在遇到字串的情況就不能了,因為字串是無限的,根本就表示不完,所以一定是會發生雜湊衝突的,一但發生雜湊衝突,點陣圖就不好用了,因為有二個字串的雜湊值是相同的,如果其中乙個字串被新增進去了,那它的那個位置就會被置1,可是我們在用另乙個字串去驗證的時候,因為雜湊值相同,所以發現存在,就返回true,但實際上它是不存在的,這就造成了錯誤,所以出現布隆過濾器來解決這個問題

但實際上布隆過濾器不能完全解決這個問題(事實上現在還沒有方法完全解決這個問題),因為它採用的是一種減少雜湊衝突的方法,就是使用雜湊函式,就是因為字串本來是無限的使用雜湊函式計算後數值可能會很大,但我們的空間到底開多大,要看我們要存多少個字串,每個字串的狀態也就佔乙個位,但它們不能像點陣圖一樣,按算出的數字直接當位置,因為它們的數字變化可能會很大,所以採用 雜湊函式先算出 雜湊值,然後再用除留取餘法,進行位置的計算,所以布隆過濾器就多了乙個成員就是我們所要占用的位數,但傳引數時,只要傳乙個就行了,因為它們都接收的是範圍,對於布隆來說,這就變成了乙個以位為個數的陣列,然後利用最終計算出的雜湊值傳進製圖中進行修改

為了保證過濾,布隆採用的使用多個雜湊函式的方法,就是用多個雜湊函式算出多個位置,然後分別置1,這樣做的好處是,減少了雜湊衝突,因為一但其中有乙個發生了雜湊衝突,被置1了,但是它在計算時,其它的位置是0,也就是一字串的狀態在多個位置存放著,只要這些位置有乙個是0那就說明其它位置是發生雜湊衝突才被置1的,就可以判定它不存在,如果全為1,那也只能說它存在的可能性大,並不能說明它一定存在,這樣做付出出的代價是,我用了空間,如果有三個雜湊函式,那它就要多用三倍的空間(也可以少用這樣發生雜湊衝突的可能就越大,就是衝突的位置就不管了,因為我們只是修改狀態並不存它),並且因為雜湊的時間複雜度 是o(1)但因為現在不知道有多少個雜湊函式,所以時間複雜度變為了o(k)k中就是雜湊函式的個數,布隆過濾器不提供刪除的原因的是,因為可能發生了雜湊衝突,當我們把要刪除元素的狀態都置為0時,發生雜湊衝突的那個元素有的位置也被置0了,像剛才說的只要有乙個為0,就代表它不存在,所以沒有提供刪除操作

它的實現,一定有乙個構造來接收所要用的兩個引數,新增時,先計算雜湊值然後傳給位圖,測試時,用所以的雜湊函式依次測試,如果有乙個為0,就返回false

布隆過濾器開空間時,因為要用多個雜湊函式,但是直接開對就倍數的空間又太浪費,不開那麼大雜湊衝突又多,所以有一群叫做大佬的人,經過各種數學計算,給出了乙個開空間的公式,m = k / ln2 * range ,其中k是你雜湊函式的個數,range是你要開的空間的大小,m就是計算出來的你實際得開的空間的大小

布隆過濾器加入刪除操作的方法:

原本布隆是不支援刪除操作,因為這個會造成錯誤,造成錯誤的原因是,我們只用了1和0來作狀態,所以在發生雜湊衝突後,我們又刪除其中乙個就會造成另乙個錯誤,究其原因還是不能對多個狀態進行記錄,所以我們可以引用計數,不用乙個位來記錄狀態,而是用乙個int來記錄狀態,也就是32位能記錄40多億個,用int的原因是:我們一般用到布隆就是碰到字串了,所以用int也不算太大,並且,因為我們在計算字串的雜湊值時,通常是轉成int型的數字,所以用32位的int來記錄多個 狀態比較靠譜 ,不然後太小的話當狀態太多溢位時,會造成迴繞,用int後就用不到位圖了,因為我們的int就相當於是乙個單元,相當於在經過雜湊對映後直接在陣列中改變狀態

所以問題就來了,這麼做的話空間就太大了,如果使用多個雜湊函式,如用5個,就是大概快20個位元組的空間,我們處理的是海量資料的話,開銷太大了,但是即使是這樣做,也是很好的,因為相比較存每乙個字串的話,空間還是相對來說小的

這樣做後,在刪除某個狀態時,只需要讓對應單元的狀態數字-1就行了

#include

#include

using

namespace std;

class

bitset

void

set(size_t n)

void

reset

(size_t n)

bool

test

(size_t n)

private

: vector<

int> _bits;};

void

testbitset()

else

}//k = (m / range) * ln2

//m = k / ln2 * range

//k / 0.7 * range

struct hashfun1

return hash;}}

;struct hashfun2

return hash;}}

;struct hashfun3

return hash;}}

;template

<

classt,

class

hashfun1

,class

hashfun2

,class

hashfun3

>

class

bloomfilter

void

set(

const t& data)

bool

test

(const t& data)

size_t index2 =

hashfun2()

(data)

% _bitcount;if(

!_bitset.

test

(index2)

) size_t index3 =

hashfun3()

(data)

% _bitcount;if(

!_bitset.

test

(index3)

)return

true;}

private

: bitset _bitset;

size_t _bitcount;};

intmain()

else

system

("pause");

return0;

}

C 布隆過濾器

我們在玩手機的時候,軟體會給我們推送一些新訊息,軟體如何保證我們哪些訊息看過,哪些訊息沒看過呢?解決辦法 用乙個伺服器記錄我們看過的內容,為了保證能夠快速查詢,我們可以使用雜湊表儲存使用者資訊,但是浪費空間,我們使用位圖進行儲存,但是不能解決雜湊衝突,將雜湊表與位圖結合 布隆過濾器。是一種概率性資料...

布隆過濾器

布隆過濾器 bloom filter 是1970年由布隆提出的。它實際上是乙個很長的二進位制向量和一系列隨機對映函式。布隆過濾器可以用於檢索乙個元素是否在乙個集合中。它的優點是空間效率和查詢時間都遠遠超過一般的演算法,缺點是有一定的誤識別率和刪除困難。如果想要判斷乙個元素是不是在乙個集合裡,一般想到...

布隆過濾器

布隆過濾器的概念 如果想要判斷乙個元素是不是在乙個集合裡,一般想到的是將所有元素儲存起來,然後通過比較確定。鍊錶,樹等等資料結構都是這種思路.但是隨著集合中元素的增加,我們需要的儲存空間越來越大,檢索速度也越來越慢 o n o logn 不過世界上還有一種叫作雜湊表 又叫 雜湊表,hash tabl...