亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C++ > 正文

C++ 數據結構之布隆過濾器

2020-01-26 14:06:03
字體:
來源:轉載
供稿:網友

布隆過濾器

一、歷史背景知識

   布隆過濾器(Bloom Filter)是1970年由布隆提出的。它實際上是一個很長的二進制向量和一系列隨機映射函數。布隆過濾器可以用于檢索一個元素是否在一個集合中。它的優點是空間效率和查詢時間都遠超過一般的算法,缺點是有一定的誤識別率和刪除錯誤。而這個缺點是不可避免的。但是絕對不會出現識別錯誤的情況出現(即假反例False negatives,如果某個元素確實沒有在該集合中,那么Bloom Filter 是不會報告該元素存在集合中的,所以不會漏報)

在 FBI,一個嫌疑人的名字是否已經在嫌疑名單上;在網絡爬蟲里,一個網址是否被訪問過等等。最直接的方法就是將集合中全部的元素存在計算機中,遇到一個新 元素時,將它和集合中的元素直接比較即可。一般來講,計算機中的集合是用哈希表(hash table)來存儲的。它的好處是快速準確,缺點是費存儲空間。當集合比較小時,這個問題不顯著,但是當集合巨大時,哈希表存儲效率低的問題就顯現出來 了。

比如說,一個象 Yahoo,Hotmail 和 Gmai 那樣的公眾電子郵件(email)提供商,總是需要過濾來自發送垃圾郵件的人(spamer)的垃圾郵件。一個辦法就是記錄下那些發垃圾郵件的 email 地址。由于那些發送者不停地在注冊新的地址,全世界少說也有幾十億個發垃圾郵件的地址,將他們都存起來則需要大量的網絡服務器。如果用哈希表,每存儲一億 個 email 地址, 就需要 1.6GB 的內存(用哈希表實現的具體辦法是將每一個 email 地址對應成一個八字節的信息指紋,然后將這些信息指紋存入哈希表,由于哈希表的存儲效率一般只有 50%,因此一個 email 地址需要占用十六個字節。一億個地址大約要 1.6GB, 即十六億字節的內存)。因此存貯幾十億個郵件地址可能需要上百 GB 的內存。除非是超級計算機,一般服務器是無法存儲的[2]。

二、布隆過濾器原理以及優缺點

如果想判斷一個元素是不是在一個集合里,一般想到的是將集合中所有元素保存起來,然后通過比較確定。鏈表、樹、散列表(哈希表,Hash table)等數據結構都是這種思想。但是隨著集合中元素的增加,我們需要的存儲空間越來越大。同時檢索速度也會越來越慢。

Bloom Filter 是一種空間效率很高的隨機數據結構,Bloom Filter 可以看做是對bit-map的擴展,它的原理是:

當一個元素被加入集合中時,通過K個hash函數將這個元素映射成一個位陣列(Bit array)中的K個點,將它們置成1. 檢索時,我們只需要看這些點是不是都是1就能(大約)知道集合中有沒有它:

如果這些點中有任何一個0,則被檢索元素一定不在;

如果都是1,則被檢索元素很可能在。

優點:

它的優點是空間效率和查詢時間都遠遠超過一般的算法,布隆過濾器存儲空間和插入/查詢時間都是O(K),另外,散列函數相互之間沒有關系,方便硬件并行實現,布隆過濾器不需要存儲元素本身,在某些對保密要求非常嚴格的場合有優勢。

缺點:

1、布隆過濾器的缺點和優點同樣明顯。誤算率是其中之一。隨著存入元素的增加,誤算率隨之增加。但是元素數量太少,則使用散列就可以了。

2、一般情況下不能從布隆過濾器中刪除元素,我們很容易想到把位數組變成整數數組,每插入一個元素相應的計數器加1,這樣刪除元素時將計數器減掉就可以了。然而要保證安全地刪除元素并非這么簡單。首先我們必須保證刪除的元素的確存在布隆過濾器里面,另外計數器回繞也會造成問題。

三、example

Google Chrome瀏覽器使用Bloom filter識別惡意鏈接(能用較小的存儲空間表示較大的數據集合,簡單想就是把 每一個URL都可以映射成bit)的多,并且誤判率在萬分之一以下。

C++實現

bit_set.h

#pragma once #include<iostream> using namespace std; #include<vector>  class Bitset { public:   Bitset(size_t value)   {     _a.resize((value >> 5) + 1, 0);   }   bool set(size_t num)   {     size_t index = num>>5;     size_t pos = num % 32;     if (_a[index] & (1 << (31 - pos)))     {       return false;     }     else     {       _a[index] |= (1 << (31 - pos));       _size++;       return true;     }        }   bool Reset(size_t num)   {     size_t index = num >> 5;     size_t pos = num % 32;     if (Text(num))     {       _a[index] &= ~(1 << (31 - pos));       _size--;       return true;     }     else     {       return false;     }   }   bool Text(size_t num)   {     size_t index = num >> 5;     size_t pos = num % 32;     return _a[index] & (1 << (31-pos));   } private:   vector<int> _a;   size_t _size; }; 

Hash.h

#pragma once template<class T> //各類哈希字符串轉換函數  size_t BKDRHash(const char *str) {   register size_t hash = 0;   while (size_t ch = (size_t)*str++)   {     hash = hash * 131 + ch;   }   return hash; }  template<class T> size_t SDBMHash(const char *str) {   register size_t hash = 0;   while (size_t ch = (size_t)*str++)   {     hash = 65599 * hash + ch;   }   return hash; }  template<class T> size_t RSHash(const char * str) {   size_t hash = 0;   size_t magic = 63689;   while (size_t ch = (size_t)*str++)   {     hash = hash * magic + ch;     magic *= 378551;   }   return hash; }   template<class T> size_t APHash(const char *str) {   register size_t hash = 0;   size_t ch;   for (long i = 0; ch = (size_t)*str++; i++)   {     if ((i & 1) == 0)     {       hash ^= ((hash << 7) ^ ch ^ (hash >> 3));     }     else     {       hash ^= (~((hash << 11) ^ ch ^ (hash >> 5)));     }   }   return hash; }   template<class T> size_t JSHash(const char* str) {   if (!*str)   {     return 0;   }   size_t hash = 1315423911;   while (size_t ch = (size_t)*str++)   {     hash ^= ((hash << 5) + ch + (hash >> 2));   }   return hash; } 

Bloom_Filter.h

#pragma once  #include"bite_set.h" #include"Hash.h" #include<string>  template<class T> struct __HashFunk1 {   size_t operator()(const T& key)   {     return BKDRHash<T>(key.c_str());   } };  template<class T> struct __HashFunk2 {   size_t operator()(const T& key)   {     return SDBMHash<T>(key.c_str());   } };   template<class T> struct __HashFunk3 {   size_t operator()(const T& key)   {     return RSHash<T>(key.c_str());   } };  template<class T> struct __HashFunk4 {   size_t operator()(const T& key)   {     return APHash<T>(key.c_str());   } };  template<class T> struct __HashFunk5 {   size_t operator()(const T& key)   {     return JSHash<T>(key.c_str());   } };   template<class K = string, class HashFunk1 = __HashFunk1<K>, class HashFunk2 = __HashFunk2<K>, class HashFunk3 = __HashFunk3<K>, class HashFunk4 = __HashFunk4<K>, class HashFunk5 = __HashFunk5<K>>  class BoolFilter { public:   BoolFilter(size_t n)     :_a(n * 10)     , _range(n * 10)   {}    void set(const K& key)   {     _a.set(HashFunk1()(key) % _range);     _a.set(HashFunk2()(key) % _range);     _a.set(HashFunk3()(key) % _range);     _a.set(HashFunk4()(key) % _range);     _a.set(HashFunk5()(key) % _range);   }    bool Text(const K& key)   {     if (!_a.Text(HashFunk1()(key)% _range))       return false;     if (!_a.Text(HashFunk2()(key) % _range))       return false;     if (!_a.Text(HashFunk3()(key) % _range))       return false;     if (!_a.Text(HashFunk4()(key) % _range))       return false;     if (!_a.Text(HashFunk5()(key) % _range))       return false;     return true;   } private:   Bitset _a;   size_t _range; }; 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
色午夜这里只有精品| 最近2019中文字幕一页二页| 日韩欧美精品免费在线| 欧美日韩亚洲激情| 国产ts一区二区| 亚洲国产99精品国自产| 精品久久久香蕉免费精品视频| 97精品久久久中文字幕免费| www.日本久久久久com.| 亚洲加勒比久久88色综合| 欧美成人全部免费| 国产剧情日韩欧美| 欧美一级片在线播放| 大伊人狠狠躁夜夜躁av一区| 久99九色视频在线观看| 国内精久久久久久久久久人| 欧美日韩在线视频一区二区| 成人在线中文字幕| 欧美日本中文字幕| 日日骚av一区| 欧美激情精品久久久久久久变态| 亚洲一区二区少妇| 久久久久久久一区二区| 狠狠久久五月精品中文字幕| 亚洲福利视频专区| 欧美野外猛男的大粗鳮| 97在线免费观看| 国产精品99久久久久久久久| 一区二区三区高清国产| 国产精品极品在线| 狠狠躁天天躁日日躁欧美| 91美女福利视频高清| 久久久久久美女| 米奇精品一区二区三区在线观看| 中文字幕成人精品久久不卡| 久久久精品国产网站| 日韩亚洲一区二区| 亚洲网站在线播放| 亚洲毛片在线看| 国产成人综合久久| 国产精品久久久久77777| 国产一区二区丝袜| 亚洲xxxxx| 亚洲欧美激情另类校园| 国产香蕉一区二区三区在线视频| 亚洲精品视频播放| 亚洲激情电影中文字幕| 成人久久精品视频| 国产999精品| 亚洲午夜未删减在线观看| 欧美午夜精品在线| 亚洲性视频网址| 在线视频欧美日韩精品| 亚洲国产日韩欧美在线动漫| 欧美成人第一页| 欧美激情第6页| 久久久女女女女999久久| 中文字幕欧美国内| 尤物九九久久国产精品的分类| 欧美极品少妇与黑人| 欧美亚洲成人免费| 欧美高清videos高潮hd| 欧美大片免费观看在线观看网站推荐| 久久在线免费观看视频| 欧美性猛交xxxx富婆弯腰| 成人精品福利视频| 欧美国产日韩视频| 日韩av免费在线播放| 亚洲电影在线观看| 久热精品视频在线观看一区| 精品国产福利在线| 久久亚洲一区二区三区四区五区高| 日韩经典中文字幕在线观看| 日韩中文字幕久久| 668精品在线视频| 成人在线观看视频网站| 欧美激情图片区| 亚洲成人在线视频播放| 日韩免费黄色av| 国产免费久久av| 欧美视频在线看| 日韩欧美成人区| 欧美激情在线播放| 欧美视频在线视频| 亚洲国产天堂久久综合网| 国产日韩亚洲欧美| 亚洲丁香婷深爱综合| 国产精品久在线观看| 国产精品69久久| 亚洲国产欧美一区二区丝袜黑人| 亚洲人成电影网站色xx| 欧美日韩免费一区| 日韩一区在线视频| 成人免费视频xnxx.com| 国产精品一二区| 欧美精品成人91久久久久久久| 日韩av手机在线| 亚洲最大av在线| 亚洲毛片在线看| 国产精品色悠悠| 国产精品视频自拍| 91在线免费看网站| 国产精品日韩在线播放| 丰满岳妇乱一区二区三区| 国产精品久久久久高潮| 国产欧美日韩免费| 色偷偷av一区二区三区乱| 91久久精品国产91久久性色| 亚洲免费福利视频| 中文字幕自拍vr一区二区三区| 亚洲图片在区色| 日韩成人在线观看| 亚洲欧美日韩天堂| 欧美野外wwwxxx| 精品国产欧美一区二区五十路| 国产一区二区三区精品久久久| 国产精品高潮呻吟久久av无限| 亚洲最新中文字幕| 91欧美激情另类亚洲| 亚洲成avwww人| 久久97精品久久久久久久不卡| 亚洲在线观看视频| 国产精品a久久久久久| 国产免费一区二区三区在线能观看| 2019中文字幕在线观看| 国产精品日本精品| 欧美二区乱c黑人| 国产精品一区二区三区在线播放| xxx欧美精品| 日韩精品免费在线播放| 98视频在线噜噜噜国产| 欧美三级欧美成人高清www| 在线日韩精品视频| 久久国产精品免费视频| 欧美裸体xxxxx| 日本精品视频在线观看| 91精品国产自产在线| 欧美麻豆久久久久久中文| 中文字幕亚洲欧美在线| 日本免费一区二区三区视频观看| www.xxxx精品| 欧美精品在线免费| 亚洲第一网站男人都懂| 日韩有码在线播放| 国外成人性视频| 日韩在线欧美在线国产在线| 国产精品亚洲美女av网站| 欧美国产视频日韩| 日本高清视频一区| 国产精品网站大全| 国产精品久久久久久婷婷天堂| 亚洲mm色国产网站| 九九视频直播综合网| 日本成人免费在线| 亚洲欧美日韩爽爽影院| 91视频免费网站| 福利视频导航一区| 久久精品视频播放| 色综合天天综合网国产成人网| 国产精品扒开腿做爽爽爽的视频| 精品国偷自产在线视频99| 国产成人激情视频| 国产精品自产拍在线观看| 欧美午夜片在线免费观看|