**:
bloom filter(布隆過濾器)主要用於判斷某個元素是否屬於集合內,但是這種判斷不是一定正確的。
經典問題:
假設你有數量非常龐大的url集合,現在給你乙個新的url,要你快速判斷這個url是否在上述的url集合中。
解決這個問題比較原始的方法是:先用乙個陣列把所有url存起來,然後再掃瞄這個陣列,判斷裡面是否有元素與新的這個url相同。這樣做會耗費非常大的空間和時間,是非常不妥的一種做法。
另一種非常快速的方法就是使用布隆過濾器了。如果布隆過濾器說乙個元素在某個集合內,那麼這個元素是很有可能在這個集合內的,但不是百分之百在;相反,如果布隆過濾器說乙個元素不在這個集合內,那麼這個元素一定不在這個集合內。
原理:布隆過濾器主要使用的是hash函式,並且是同時使用多個hash函式,以便減少hash衝突。
首先,假設有7個hash函式,分別是h1(), h2() ….h7(),這裡hash函式的具體內容是不定的,看你具體的程式和應用來決定。然後有乙個位陣列bits,元素個數為m吧,初始化為0.
下面先說往集合裡新增元素的過程:
給你乙個元素e,你要把它通過布隆過濾器新增到某個集合裡。
首先,分別用上面的7個hash函式對e取hash值,假設結果如下:
r1 = h1(e) = 5,
r2 = h2(e) = 6,
r3 = h3(e) = 1,
r4 = h4(e) = 7,
r5 = h5(e) = 6,
r6 = h6(e) = 10,
r7 = h7(e) = 9.
這裡需要注意的是,這幾個hash函式中有可能返回值是相同的(比如上面的r2和r5)。
根據上面的結果,把bits對應位置為1(重複只需置一次就可以了):
bits[5] = 1
bits[6] = 1,
bits[1] = 1,
bits[7] = 1,
bits[10] = 1,
bits[9] = 1.
這就把e通過布隆過濾器加入到了集合中來。
現在假設又來乙個元素e2,要新增到集合中來。假設用7個hash函式做hash得:
r1 = h1(e2) = 3,
r2 = h2(e2) = 1,
r3 = h3(e2) = 6,
r4 = h4(e2) = 14,
r5 = h5(e2) = 11,
r6 = h6(e2) = 13,
r7 = h7(e2) = 3.
再把對應bits的位置為1,
bits[3] = 1,
bits[1] = 1,
bits[6] = 1,
bits[14] = 1,
bits[11] = 1,
bits[13] = 1,
bits[3] = 1.
注意bits的長度m的大小,不要越過陣列邊界了。
經過上述兩個元素的新增,bits變成下面這樣:
bits[1] = 1,
bits[3] = 1,
bits[5] = 1,
bits[6] = 1,
bits[7] = 1,
bits[9] = 1,
bits[10] = 1,
bits[11] = 1,
bits[13] = 1,
bits[14] = 1,
其他都為0。
現在集合裡面有e1和e2兩個元素了。
現在要判斷元素e3是否在這個集合內。
首先分別用上面的7個hash函式對e3求hash,結果假設如下:
r1 = h1(e3) = 3,
r2 = h2(e3) = 1,
r3 = h3(e3) = 6,
r4 = h4(e3) = 14,
r5 = h5(e3) = 11,
r6 = h6(e3) = 13,
r7 = h7(e3) = 3.
(很明顯,這裡的結果與e2的hash結果一樣)
如果e3在集合內,那麼上面結果對應的bits位要全都為1才行,如果有乙個為0,那麼e3就不在集合內。很明顯,bits對應的位都為1,所以我們可以說e3很有可能在集合內,但不是百分之百。
如果是這種情況,e3的所有hash值對應的bits都為1,但是e3不在集合內。假設此時hash值計算結果為:
r1 = h1(e3) = 3,
r2 = h2(e3) = 6,
r3 = h3(e3) = 7,
r4 = h4(e3) = 9,
r5 = h5(e3) = 11,
r6 = h6(e3) =13,
r7 = h7(e3) = 14,
此時雖然對應bits位都為1,但是由於e3的hash結果是由e1和e2混合而來的,所以此時e3是不存在集合中的。
相反,如果計算出所有的hash值,bits對應位中有為0 的,那麼可以肯定地說這個元素一定不在集合內;因為如果在集合內的話,那麼在用布隆過濾器新增元素時,就應該把這個元素所有hash值的bits對應位都置為了1.
bloomfilter的c++**:
bloomfilter.h
[cpp]view plain
copy
//// bloomfilter.h
// bloomfilter
//// created by 劉建安 on 4/19/15.
//#ifndef bloomfilter_bloomfilter_h
#define bloomfilter_bloomfilter_h
#include "math.h"
#include "memory.h"
#include "bloomhash.h"
using
namespace
std;
class
bloomfilter;
//hash函式的種子
for(
inti = 0; i < 7; i++)
hash[i].setseed(seeds[i]);
} //判斷是否包含某個字串
bool
iscontain(string s)
return
flag;
} //新增字串
void
add(string s)
} };
#endif
bloomhash.h
[cpp]view plain
copy
//// bloomhash.h
// bloomfilter
//// created by 劉建安 on 4/19/15.
//#ifndef bloomfilter_bloomhash_h
#define bloomfilter_bloomhash_h
#include "string"
using
namespace
std;
#define numofbits (1 << 14) //bits陣列的長度
class
bloomhash
//對乙個字串求雜湊值
inthash(string s)
return
(numofbits -1) & result;
//這裡記得要減去1,否則答案有錯;&是為了保證陣列不越界
} };
#endif
main.cpp
[cpp]view plain
copy
//// main.cpp
// bloomfilter
//// created by 劉建安 on 4/19/15.
//#include
#include "bloomfilter.h"
#include "string"
using
namespace
std;
intmain(
intargc,
const
char
* argv)
else
cout << "no"
<< endl;
return
0;
}
Bloom filter(布隆過濾器)
問題 在網路爬蟲中,有乙個要考慮的問題,由於網路間的鏈結錯綜複雜,蜘蛛在網路間爬行很可能會形成 環 為了避免形成 環 就需要知道蜘蛛已經訪問過那些url。給乙個url,怎樣知道蜘蛛是否已經訪問過呢?有如下幾種方案 1.將訪問過的url儲存到資料庫。2.用hashset將訪問過的url儲存起來。那只需...
布隆過濾器(Bloom Filter)
1.簡介 布隆過濾器是一種多雜湊函式對映的快速查詢演算法。它可以判斷出某個元素肯定不在集合裡或者可能在集合裡,即它不會漏報,但可能會誤報。通常應用在一些需要快速判斷某個元素是否屬於集合,但不嚴格要求100 正確的場合。2.原理 首先需要k個hash函式,每個函式可以把key雜湊成為1個整數 初始化時...
布隆過濾器(BloomFilter)
名稱 問題解決方法 快取穿透 查詢了乙個不存在的資料 布隆過濾器 快取擊穿 某個key的快取失效 互斥鎖快取雪崩 多個key的快取同時失效 失效時間 隨機時間 底層是乙個bit二進位制向量或叫 bit 陣列,bit 裡存放的資料非0即1。通過雜湊函式將元素對映到bit的相應位置,並將此位置置為1。如...