上篇部落格我們講到了點陣圖(bitmap):雜湊應用之位圖 ,但是位圖不是萬能的,如我們需要儲存的64bit型別的資料,還能不能用bitmap?我們來算一算:
eb(exabyte,艾位元組)這個電腦科學中統計資料量的單位有多大,有興趣的小夥伴可以查閱下資料。這個量級的bitmap,已經不是人類硬體所能承擔的了。我相信誰也不會想用集群去計算這麼乙個問題吧?所以bitmap的好處在於空間複雜度不隨原始集合內元素的個數增加而增加,而它的壞處也源於這一點 ——空間複雜度隨集合內最大元素增大而線性增大。
所以接下來,我們要引入另乙個著名的工業實現——布隆過濾器(bloom filter)。
布隆過濾器
bloomfilter的核心思想:
bloomfilter的準確性
儘管bloomfilter已經盡可能的減小雜湊衝突的概率了,但是,並不能徹底消除,因此正如上面提到的:
布隆結構
//假設布隆過濾器中元素型別為k,每個元素對應3個雜湊函式,即乙個值會對映三個位置
templateclass bloomfilter
private:
bitmap _bmp;//底層由bitmap實現
};
布隆的插入bool insert(const k& key)
布隆過濾器的查詢bool isbloomfilter(const k& key)
注意:布隆過濾器如果說某個元素不存在時,該元素一定不存在,如果該元素存在時,該元素可能存在,因為有些雜湊函式存在一定的誤判。增加和查詢元素的時間複雜度為:o(k), (k為雜湊函式的個數,一般比較小),與資料量大小無關
雜湊函式相互之間沒有關係,方便硬體並行運算
布隆過濾器不需要儲存元素本身,在某些對保密要求比較嚴格的場合有很大優勢
在能夠承受一定的誤判時,布隆過濾器比其他資料結構有這很大的空間優勢
資料量很大時,布隆過濾器可以表示全集,其他資料結構不能
使用同一組雜湊函式的布隆過濾器可以進行交、並、差運算
有誤判率,即存在假陽性(false position),即不能準確判斷元素是否在集合中(補救方法:再建立乙個白名單,儲存可能會誤判的資料)
不能獲取元素本身,只能判斷其存不存在
一般情況下不能從布隆過濾器中刪除元素(可以支援刪除,但是效率不高且浪費空間)
如果採用計數方式刪除,可能會存在計數迴繞問題
#include "bitmap.h"
#pragma once
#include using namespace std;
struct hashfunc1
return hash;
}};struct hashfunc2
return hash;
}};struct hashfunc3
return hash;
}};//假設布隆過濾器中元素型別為k,每個元素對應3個雜湊函式,即乙個值會對映三個位置
templateclass bloomfilter
bool insert(const k& key)
bool isbloomfilter(const k& key)
private:
bitmap _bmp;
size_t _size;
};
資料結構 雜湊思想應用之布隆過濾器
假設現有海量資料,例如10億個字元 理想容器 該容器儲存思想仍為點陣圖。但卻可以儲存字元,且可以處理雜湊衝突。在之前的雜湊表編寫中,雜湊擁有乙個函式,該函式可以自動識別儲存內容。實際的底層實現為 將不同型別轉換為整形。雜湊轉換演算法有很多種,其效果就是將乙個字串轉換為乙個整形的值返回,例如下面的 s...
資料結構 布隆過濾器
基於位圖的缺點 只能儲存整型,在現實中的應用有了很大的侷限性,所以又引出了一種新的雜湊變形,其實也算是點陣圖的變形 布隆過濾器。如圖,把字串經過布隆過濾器的處理,對映到位圖的多個位置,讓這幾個位置都置成1用來表示這個字串的存在。所以只要有乙個位置為0,那麼這個資料就不存在。1.本來不存在的資料,可能...
資料結構 布隆過濾器
原理 如果要判斷乙個數是不是在乙個集合裡,一半想到的是將所有的元素儲存起來,然後通過比較確定。但是隨著集合中元素的增加,需要的儲存空間越來越大,檢索速度自然會變慢。這時會有人想到使用雜湊表,將元素通過雜湊函式對映到乙個位陣列中,將相應的位元位置為1,這樣就可以判斷這個元素是不是在集合之中了。但是雜湊...