大資料處理演算法--Bloom Filter
一、布隆過濾器(Bloom Filter)的定義
布隆過濾器可以用來檢測資料是否存在於一個集合中。它是hash的擴充套件,底層就是一個位數組,每一個bit位可以表示一個數字,所以布隆過濾器是基於點陣圖來實現的。
二、布隆過濾器的原理
1、插入資料
在點陣圖中,每一個bit對應一個數字,出現一個數字就可以在相應的位上置1。但是布隆過濾器不一樣,它要處理的不僅僅是整型還有其他如string型別的資料,因此,當大量的string類資訊需要處理的時候,難免會引起大量的衝突。布隆過濾器在這裡的處理是用多個bit位來表示string型別的資料,這多個bit位通過不同的hash函式得出,這樣衝突的概率就減少了。
2、刪除資料
布隆過濾器不支援刪除資料,因為一個數據型別是由好幾個bit位來表示的,難免幾個資料的bit位會重疊,如果刪除一個bit位,其他的資料也可能受到影響。那麼如何實現布隆過濾器的刪除呢?這裡可以引入引用計數的概念,將位陣列擴充套件位整型陣列,陣列的下標對應資料通過hash函式得出的數,陣列中存放的是數字出現的次數,即引用計數。
3、檢測資料
同插入資料時一樣,這裡的資料需要用幾個hash函式得出多個bit位,如果每個bit位都存在於位陣列中,那麼這個資料可能存在。為什麼說是可能存在呢,因為有可能這個資料的幾個bit位是由其他資料置為1的。如果幾個bit中有一個為0,那麼這個資料一定就不存在了。
三、布隆過濾器的特點
1、優點:它相比於hash,紅黑樹等結構更加節省空間,而且插入效率和查詢效率都遠遠超過一般演算法
2、缺點:不支援刪除操作;查詢的結果不一定準確(結果為不存在時是準確的,為存在時是不準確的);
四、布隆過濾器的應用
像網易,QQ這樣的公眾電子郵件(email)提供商,總是需要過濾來自發送垃圾郵件的人(spamer)的垃圾郵件。
一個辦法就是記錄下那些發垃圾郵件的 email地址。由於那些傳送者不停地在註冊新的地址,全世界少說也有幾十億個發垃圾郵件的地址,將他們都存起來則需要大量的網路伺服器。
如果用雜湊表,每儲存一億個 email地址,就需要 1.6GB的記憶體(用雜湊表實現的具體辦法是將每一個 email地址對應成一個八位元組的資訊指紋,然後將這些資訊指紋存入雜湊表,由於雜湊表的儲存效率一般只有 50%,因此一個email地址需要佔用十六個位元組。一億個地址大約要 1.6GB,即十六億位元組的記憶體)。因此存貯幾十億個郵件地址可能需要上百 GB的記憶體。
而Bloom Filter只需要雜湊表 1/8到 1/4 的大小就能解決同樣的問題。
BloomFilter決不會漏掉任何一個在黑名單中的可疑地址。而至於誤判問題,常見的補救辦法是在建立一個小的白名單,儲存那些可能別誤判的郵件地址。
五、布隆過濾器的實現
#include<iostream>
#include "bitmap.h"
using namespace std;
struct HashFunc1
{
static size_t BKDRHash(const char *str)
{
unsigned int seed = 131;
unsigned int hash = 1;
while (*str)
{
hash = hash * seed + (*str++);
}
return (hash & 0x7fffffff);
}
size_t operator()(const std::string &str)
{
return BKDRHash(str.c_str());
}
};
struct HashFunc2
{
static size_t BKDRHash(const char *str)
{
register size_t hash = 0;
while (size_t ch = (size_t)*str++)
{
hash = hash * 131 + ch;
}
return hash;
}
size_t operator()(const std::string &str)
{
return BKDRHash(str.c_str());
}
};
struct HashFunc3
{
static size_t BKDRHash(const char *str)
{
if (!*str) // 這是由本人新增,以保證空字串返回雜湊值0
return 0;
register size_t hash = 1315423911;
while (size_t ch = (size_t)*str++)
{
hash ^= ((hash << 5) + ch + (hash >> 2));
}
return hash;
}
size_t operator()(const std::string &str)
{
return BKDRHash(str.c_str());
}
};
struct HashFunc4
{
static size_t BKDRHash(const char *str)
{
register size_t hash = 0;
size_t magic = 63689;
while (size_t ch = (size_t)*str++)
{
hash = hash * magic + ch;
magic *= 378551;
}
return hash;
}
size_t operator()(const std::string &str)
{
return BKDRHash(str.c_str());
}
};
struct HashFunc5
{
static size_t BKDRHash(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;
}
size_t operator()(const std::string &str)
{
return BKDRHash(str.c_str());
}
};
template<class K=string,
class Hash1 = HashFunc1,
class Hash2 = HashFunc2,
class Hash3 = HashFunc3,
class Hash4 = HashFunc4,
class Hash5 = HashFunc5>
class Bloom
{
public:
Bloom(size_t size)
:_map(size)
{}
void Set(string str1)
{
size_t hash1 = HashFunc1()(str1);
_map.Set(hash1%_map.Size());
size_t hash2 = HashFunc2()(str1);
_map.Set(hash2%_map.Size());
size_t hash3 = HashFunc3()(str1);
_map.Set(hash3%_map.Size());
size_t hash4 = HashFunc4()(str1);
_map.Set(hash4%_map.Size());
size_t hash5 = HashFunc5()(str1);
_map.Set(hash5%_map.Size());
}
void Unset()
{
}
bool Test(string str1)
{
size_t hash1 = HashFunc1()(str1);
if (false == _map.test(hash1%_map.Size()))
return false;
size_t hash2 = HashFunc2()(str1);
if (false == _map.test(hash2%_map.Size()))
return false;
size_t hash3 = HashFunc3()(str1);
if (false == _map.test(hash3%_map.Size()))
return false;
size_t hash4 = HashFunc4()(str1);
if (false == _map.test(hash4%_map.Size()))
return false;
size_t hash5 = HashFunc5()(str1);
if (false == _map.test(hash5%_map.Size()))
return false;
return true;
}
private:
bitmap _map;
};
以下是點陣圖的實現
#pragma once
#include<iostream>
#include <vector>
using namespace std;
class bitmap
{
public:
bitmap(size_t size)
:_size(size)
{
map = new int[(size >> 5) + 1];
memset(map, 0, sizeof(map));
}
~bitmap()
{
delete[]map;
}
void Set(size_t num)
{
int index = num >> 5;
int pos = num % 32;
map[index] |= (1 << (pos-1));
}
void Unset(size_t num)
{
int index = num >> 5;
int pos = num % 32;
map[index] &= ~(1 << (pos-1));
}
bool test(size_t num)
{
int index = num >> 5;
int pos = num % 32;
if (((map[index]>>(pos-1))&1)==1)
return true;
return false;
}
size_t Size()
{
return _size;
}
private:
int*map;
size_t _size;
};
相關推薦
大資料處理演算法--Bloom Filter
一、布隆過濾器(Bloom Filter)的定義 布隆過濾器可以用來檢測資料是否存在於一個集合中。它是hash的擴充套件,底層就是一個位數組,每一個bit位可以表示一個數字,所以布隆過濾器是基於點陣圖來實現的。 二、布隆過濾器的原理 1、插入資料 在點陣圖中,每一個bi
海量資料處理演算法—Bloom Filter
1. Bloom-Filter演算法簡介 Bloom-Filter,即布隆過濾器,1970年由Bloom中提出。它可以用於檢索一個元素是否在一個集合中。Bloom Filter(BF)是一種空間效率很高的隨機資料結構,它利用位陣列很簡潔地表示一個集合,並能判斷一個
大資料處理演算法三:分而治之/hash對映 + hash統計 + 堆/快速/歸併排序
百度面試題1、海量日誌資料,提取出某日訪問百度次數最多的那個IP。 IP 是32位的,最多有個2^32個IP。同樣可以採用對映的方法,比如模1000,把整個大檔案對映為1000個小檔案,再找出每個小文中出現頻率最大的 IP(可以採用hash_map進行頻率統計,然後再找出頻
海量資料處理之Bloom Filter詳解
一、什麼是Bloom Filter Bloom Filter是一種空間效率很高的隨機資料結構,它的原理是,當一個元素被加入集合時,通過K個Hash函式將這個元素對映成一個位陣列(Bit array)中的K個點,把它們置為1。檢索時,我們只要看看這些點是不是都是1就(大約
大資料經典演算法——bit-map與bloom filter
明白了雜湊的原理,bit-map就好說了。 bit-map的核心思想是:所謂的Bit-map就是用一個bit位來標記某個元素對應的Value, 而Key即是該元素。每一個bit空間都是儲存單元,而不像
《資料演算法:Hadoop_Spark大資料處理技巧》艾提拉筆記.docx 第1章二次排序:簡介 19 第2章二次排序:詳細示例 42 第3章 Top 10 列表 54 第4章左外連線 96 第5
《資料演算法:Hadoop_Spark大資料處理技巧》艾提拉筆記.docx 第1章二次排序:簡介 19 第2章二次排序:詳細示例 42 第3章 Top 10 列表 54 第4章左外連線 96 第5章反轉排序 127 第6章
(二)大資料處理:基於MapReduce的大圖劃分演算法綜述
【宣告:鄙人菜鳥一枚,寫的都是初級部落格,如遇大神路過鄙地,請多賜教;內容有誤,請批評指教,如有雷同,屬我偷懶轉運的,能給你帶來收穫就是我的部落格價值所在。】 今天一位同事跟我談起Hadoop,剛好這期部落格我也正準備寫點這方面相關的綜述,就跟他聊了聊。
《資料演算法-Hadoop/Spark大資料處理技巧》讀書筆記(一)——二次排序
寫在前面: 在做直播的時候有同學問Spark不是用Scala語言作為開發語言麼,的確是的,從網上查資料的話也會看到大把大把的用Scala編寫的Spark程式,但是仔細看就會發現這些用Scala寫的文章
《資料演算法-Hadoop/Spark大資料處理技巧》讀書筆記(四)——移動平均
移動平均:對時序序列按週期取其值的平均值,這種運算被稱為移動平均。典型例子是求股票的n天內的平均值。 移動平均的關鍵是如何求這個平均值,可以使用Queue來實現。 public class MovingAverageDriver { public
經典演算法題:大資料處理常見演算法題
第一部分、十道海量資料處理 1、海量日誌資料,提取出某日訪問百度次數最多的那個IP。 此題,在我之前的一篇文章演算法裡頭有所提到,當時給出的方案是:IP的數目還是有限的,最多2^32個,所以可以考慮使用hash將ip直接存入記憶體,然後進行統計。 再詳細介紹下此方案:
php 大資料量及海量資料處理演算法總結
下面的方法是我對海量資料的處理方法進行了一個一般性的總結,當然這些方法可能並不能完全覆蓋所有的問題,但是這樣的一些方法也基本可以處理絕大多數遇到的問題。下面的一些問題基本直接來源於公司的面試筆試題目,方法不一定最優,如果你有更好的處理方法,歡迎與我討論。 1.Bloom f
DKhadoop大資料處理平臺監控資料介紹
標題:DKhadoop大資料處理平臺監控資料介紹 2018年國內大資料公司50強榜單排名已經公佈了出來,大快以黑馬之姿闖入50強,並摘得多項桂冠。Hanlp自然語言處理技術也榮膺了“2018中國資料星技術”獎。對這份榜單感興趣的可以找一下看看。本篇承接上一篇《DKM平臺監控引數說明》,繼續就
大資料(演算法知識)
大資料問題 Map-Reduce和Hadoop逐漸成為熱門。 1介紹雜湊函式 雜湊函式又叫雜湊函式,雜湊函式的輸入域可以是非常大的範圍,但是輸出域是固定範圍。假設為s。 雜湊函式性質: 1:典型的雜湊函式都擁有無限的輸入值域; 2:輸入值相同時,返回值一樣; 3:輸入值不
淺談大資料處理
剛接觸大資料處理,將大資料處理的框架記錄下來,之後深入的研究。 大資料處理的必要性 目前網際網路中資料的數量正在飛速的增長,首先是G為單位,然後是T級別、P級別、E級別。資料雖然很多,但是我們往往只慣性我們感興趣的那一部分,因此我們需要對海量資料進行處理獲取有價值的資訊來為我們所用。比如
大資料處理神器map-reduce實現(僅python和shell版本)
熟悉java的人直接可以使用java實現map-reduce過程,而像我這種不熟悉java的怎麼辦?為了讓非java程式設計師方便處理資料,我把使用python,shell實現streaming的過程,也即為map-reduce過程,整理如下: 1.如果資料不在hive裡面,而在
海量資料處理演算法—Bit-Map
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
Hadoop Streaming 做大資料處理詳解
-------------------------------------------------------------------------- 以下內容摘自寒小陽老師大資料課程內容 -----------------------------
最主流的五個大資料處理框架的優勢對比
我深入分析了五個大資料處理框架:Hadoop,Spark,Flink,Storm,Samaza Hadoop 頂尖的框架之一,大資料的代名詞。Hadoop,MapReduce,以及其生態系統和相關的技術,比如Pig,Hive,Flume,HDFS等。Hadoop是第一個,在工業
Python大資料處理庫PySpark實戰
https://cloud.tencent.com/developer/article/1096712 Spark的安裝和使用(Python版) http://dblab.xmu.edu.cn/blog/1689-2/ https://blog.csdn.net/qq_14959801/
大資料處理——雙層桶
轉載:http://diducoder.com/mass-data-topic-6-multi-dividing.html 【什麼是雙層桶】 事實上,與其說雙層桶劃分是一種資料結構,不如說它是一種演算法設計思想。面對一堆大量的資料我們無法處理的時候,我們可以將其分成一個個小的單元,