国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

哈希與位圖的結合--布隆過濾器與哈希切分

這篇具有很好參考價值的文章主要介紹了哈希與位圖的結合--布隆過濾器與哈希切分。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

上一章講了位圖,我們知道了在海量數(shù)據(jù)中查找一個數(shù)是否存在,可以用每一個比特位標識。

但是位圖只能處理整數(shù),要是字符串或者其它的呢,位圖便無法處理了,這個時候便需要用到布隆過濾器了.

目錄

布隆過濾器提出

布隆過濾器概念

布隆過濾器的實現(xiàn)以及最優(yōu)值

?哈希切分


布隆過濾器提出

我們在看b站視頻時,它會給我們不停地推薦新的內(nèi)容,它每次推薦時要去重,去掉那些已經(jīng)看過的內(nèi)容。問題來了,b站推薦系統(tǒng)如何實現(xiàn)推送去重的? 用服務器記錄了用戶看過的所有歷史記錄,當b站推薦系統(tǒng)推薦視頻時會從每個用戶的歷史記錄里進行篩選,過濾掉那些已經(jīng)存在的記錄。 如何快速查找呢?
1. 用哈希表存儲用戶記錄,缺點:浪費空間
2. 用位圖存儲用戶記錄,缺點:位圖一般只能處理整形,如果內(nèi)容編號是字符串,就無法處理了。
3. 將哈希與位圖結合,即布隆過濾器

布隆過濾器概念

布隆過濾器(Bloom Filter)是一種概率型的數(shù)據(jù)結構,用于快速判斷一個元素是否存在于一個集合中。它基于位圖(或稱為位數(shù)組)和多個哈希函數(shù)構成。

布隆過濾器的主要目標是在存儲空間相對較小的情況下,實現(xiàn)高效的成員查詢。它通過使用多個哈希函數(shù)將要查詢的元素映射到位圖中的多個位上。當一個元素要插入布隆過濾器時,通過多個哈希函數(shù)計算出多個索引位置,并將對應位設置為1。當判斷一個元素是否存在時,再次通過多個哈希函數(shù)計算出多個索引位置,并檢查對應位是否都為1。如果有任何一個位為0,則可以確定該元素一定不存在于集合中;如果所有位都為1,則表示該元素可能存在于集合中,但有一定的誤判率。

注意,只有判斷一個數(shù)據(jù)存在的時候才會有誤判。

因為如果判斷一個數(shù)據(jù)它存在了,但是它可能和別的數(shù)據(jù)沖突了,即別的數(shù)據(jù)占的這些位恰好是這個數(shù)據(jù)的那些位。這樣就會造成誤判。

我舉個例子可以說明一下:

哈希與位圖的結合--布隆過濾器與哈希切分,哈希算法,布隆過濾器,C++,哈希切分

而判斷一個數(shù)據(jù)不存在這是絕對不可能誤判的,因為不存在說明別的數(shù)據(jù)都還沒有占用這些位,一定沒有和這個數(shù)據(jù)相同的數(shù)據(jù)存在,因為如果存在了,對應的所有位就都是1了,此時便會判它存在了.

這個誤判是不可能去掉的,但是可以降低誤判的概率。比如增加多個哈希函數(shù)。

這樣的話,每個數(shù)據(jù)對應的位就會多了,這樣重合的概率就會更低。

例如之前一個數(shù)據(jù)對應兩個位,現(xiàn)在對應了三個位,是不是重合的概率又降低了呢?

雖然原來我們兩個位沖突了,現(xiàn)在又多了一個位,又多了一個機會,此時便相當于降低了誤判率。

但是也不能盲目的增加哈希函數(shù),具體會有一個合適的值.

哈希與位圖的結合--布隆過濾器與哈希切分,哈希算法,布隆過濾器,C++,哈希切分

?如果映射函數(shù)的越多,空間消耗就會增多,就失去了原本的優(yōu)勢

這個會被應用在哪些地方呢?

比如訪問一個網(wǎng)站,會有黑名單用戶,每個用戶訪問的時候,都需要判斷一下是不是黑名單用戶。

我們?nèi)绻看味家?shù)據(jù)庫中查找,那么經(jīng)過網(wǎng)絡傳輸?shù)冗^程會使效率變得非常低下,所以是不被采用的。

這個時候便用到了我們的布隆過濾器,每當有用戶訪問,先查找存在不存在,有兩種情況:

1.存在:如果存在,我們才再次需要去數(shù)據(jù)庫中查找,因為存在會有誤判,萬一人家不是黑名單用戶,你卻誤判成了黑名單,這當然是不合理的,這個時候才去數(shù)據(jù)庫中查找。

2.不存在:不存在那就說明這個人一定不是黑名單用戶了,因為不存在不會有誤判,直接返回即可:

哈希與位圖的結合--布隆過濾器與哈希切分,哈希算法,布隆過濾器,C++,哈希切分

還有一個我們常見的情景,就是在注冊申請一個賬號的時候,比如輸入昵稱的時候,有的后面會立馬顯示“此昵稱已被占用”。這其實就是應用了布隆過濾器。

當你輸入一個名字的時候,如果利用布隆過濾器查找,發(fā)現(xiàn)存在了,會給你提示已經(jīng)存在,但是這個名字一定是存在的嗎?那不一定,畢竟有可能是誤判。

但是你也不會察覺到,占用就占用了唄,然后換一個就行。當然這也對這個公司有好處,報總比不報好,萬一就是已經(jīng)存在的呢,這樣就不好了。

但是不存在的話,就不會報,因為它一定不存在了。這也是前面一直所說的.

哈希與位圖的結合--布隆過濾器與哈希切分,哈希算法,布隆過濾器,C++,哈希切分

布隆過濾器的實現(xiàn)以及最優(yōu)值

由于C++STL庫中并沒有布隆過濾器,所以得靠我們自己手動實現(xiàn)。

首先由于布隆過濾器的數(shù)據(jù)類型不再只是整數(shù),所以我們要利用模板。

可以定義K為數(shù)據(jù)的類型,那么我們每次需要給位圖開多大空間呢?

總不能一上來開41億,比如就100個數(shù)據(jù),開這么大就有點浪費了,所以再給出一個非類型模板參數(shù)N,代表數(shù)據(jù)的個數(shù),然后在成員變量中定義一個_ratio表示倍數(shù),每次開N*_ratio的空間即可。

可能有同學會有疑問,之前位圖不是說開多少空間取決于數(shù)據(jù)范圍嗎?這個怎么不用?

因為位圖采用的是直接定址法,它這個數(shù)據(jù)是多少,它就會對應在位圖的相應位置,所以數(shù)據(jù)范圍的大小決定了開多少空間。

而布隆過濾器是對每個數(shù)據(jù)采用了哈希映射,而且是多個哈希映射,這樣當然不需要多么大的空間了。比如一個數(shù)據(jù)1,和99999999,采用了哈希映射后,1對應的位圖中是1,2,3,而99999999對應的位圖是1,3,4、這個只是一個假設,目的是理解為什么不用根據(jù)數(shù)據(jù)范圍來開空間。

然后毋庸置疑,就是對應的哈希函數(shù)模板,那么具體定義多少個哈希映射函數(shù)呢?

不僅如此,布隆過濾器(內(nèi)部其實就是一個位圖)的長度也影響了誤判率,那么長度為多少合適呢?

這個有一套數(shù)學理論和實驗證明,這里我們只看一下最終結果和公式:

“很顯然,過小的布隆過濾器很快所有的 bit 位均為 1,那么查詢?nèi)魏沃刀紩祷亍翱赡艽嬖凇?,起不到過濾的目的了。布隆過濾器的長度會直接影響誤報率,布隆過濾器越長其誤報率越小。

另外,哈希函數(shù)的個數(shù)也需要權衡,個數(shù)越多則布隆過濾器 bit 位置位 1 的速度越快,且布隆過濾器的效率越低;但是如果太少的話,那我們的誤報率會變高”

哈希與位圖的結合--布隆過濾器與哈希切分,哈希算法,布隆過濾器,C++,哈希切分

k 為哈希函數(shù)個數(shù),m 為布隆過濾器長度,n 為插入的元素個數(shù),p 為誤判率

那么具體該如何選擇k和m的值是最優(yōu)的呢?

有兩個公式:

哈希與位圖的結合--布隆過濾器與哈希切分,哈希算法,布隆過濾器,C++,哈希切分

根據(jù)這兩個公式可以選出最優(yōu)的m和k的值。

然后下面就是布隆過濾器的代碼,代碼不唯一的,具體根據(jù)m和k的值進行調(diào)整。

//N表示準備要映射N個值.
template<size_t N,class K,
class Hash1,class Hash2,class Hash3>
class BloomFilter
{
public:
	void Set(const K& key)
	{
		size_t hash1 = Hash1()(key) % (_ratio * N);
		_bits.set(hash1);
		size_t hash2 = Hash2()(key) % (_ratio * N);
		_bits.set(hash2);
		size_t hash3 = Hash3()(key) % (_ratio * N);
		_bits.set(hash3);
	}
	bool Test(const K& key)
	{
		size_t hash1 = Hash1()(key) % (_ratio * N);
		if (!bits.test(hash1))
			return false;
		size_t hash2 = Hash2()(key) % (_ratio * N);
		if (!bits.test(hash2))
			return false;
		size_t hash3 = Hash3()(key) % (_ratio * N);
		if (!bits.test(hash3))
			return false;
		return true;//可能存在誤判
	}
private:
	const static size_t _ratio = 5;
	bitset<_ratio*N> _bits;
};

這是主體部分的代碼,可以看到以上代碼中用了3個哈希函數(shù),具體每個哈希算法怎么實現(xiàn),則由自己進行決定。也可以在網(wǎng)上搜索一些哈希相關的算法。

然后我們定義3個類,每個類中重載()運算符,然后進行哈希算法的實現(xiàn)。最后創(chuàng)建對象時,把這三個類傳入即可。

下面講解兩道布隆過濾器相關的題目:

1、?如何擴展BloomFilter使得它支持刪除元素的操作?

首先我們要知道,布隆過濾器一般情況下是不能被刪除的。大家想一想,為什么?

因為位圖中的某一個位可能是兩個字符串的位,即它們有公共比特位,例如這張圖:

哈希與位圖的結合--布隆過濾器與哈希切分,哈希算法,布隆過濾器,C++,哈希切分

如果我們想刪除百度,即將百度的對應的位全部置為0,b站也會受到影響,?最后只剩下1個位了。

這樣在查找的時候,便也查找不到b站了,所以對其他數(shù)據(jù)也造成影響了。

那么我們能不能強行改造一下呢?

當然是可以的,我們另創(chuàng)建一個位來保存每個位置1的個數(shù)count,若每次刪除,則將count減1。

如果count為0說明此時已經(jīng)沒有數(shù)據(jù)再占用這個位了,便可以置為0了,否則,count--即可.

當然這么做會增加了空間的消耗,會削弱布隆過濾器的優(yōu)勢,與其有這些空間存這個,不如用這些空間來降低一些誤判率呢.

?哈希切分

先來看下面這個問題:

給一個超過100G大小的log file, log中存著IP地址, 設計算法找到出現(xiàn)次數(shù)最多的IP地址?

哈希與位圖的結合--布隆過濾器與哈希切分,哈希算法,布隆過濾器,C++,哈希切分

以上這張圖已經(jīng)說明了,我們可以將100G數(shù)據(jù)中的每個ip地址由哈希函數(shù)轉(zhuǎn)為整數(shù),再進行切分到不同的桶中,這樣每個桶中都有對應的ip地址了。

那么我們該如何統(tǒng)計每個桶中的ip地址的個數(shù)呢?

當然是利用map進行統(tǒng)計,如果超過1G了呢?這里也會出現(xiàn)兩種情況:

1.這個桶中不相同的ip很多,由于每次遇到不同的ip值,map都要進行插入,所以map統(tǒng)計不了。

2.這個桶中相同的ip很多,雖然有很多的ip,但是由于很多是相同的,所以直接在key對應的value上加1節(jié)課即可,并不會消耗空間。

直接使用map中的insert將每一個桶的元素插入到map中。

情況一:如果insert插入失敗,說明空間不足,new節(jié)點失敗,拋出異常。解決方法是換個哈希函數(shù),遞歸再次對這個沖突桶進行切分。

情況二:map可以正常統(tǒng)計。

這樣找到map中value值最高的即可。

2. 給兩個文件,分別有100億個query,我們只有1G內(nèi)存,如何找到兩個文件交集?分別給出精確算法和近似算法

近似算法:將一個文件中的數(shù)據(jù)全部set進布隆過濾器中,然后分別用另一個文件的數(shù)據(jù)test比對,可以淘汰一定不是交集的部分。當然淘汰完剩下的那部分數(shù)據(jù)中,也會有非交集的存在。

精確算法:這個可以參考第一個問題的哈希切分方法。

思路是:利用相同的哈希函數(shù)(記住一定相同!)將兩個文件的數(shù)據(jù)進行哈希切分,最后每個文件都會切分出許多小文件。然后我們分別比對下標相同的小文件,找出交集即可。

例如A文件切分出了A0,A1,A2...A999.

B文件切分出了B0,B1,B2....B999.

我們直接A0和B0,A1和B1,...A999和B999進行比較即可,因為兩個文件使用了相同的哈希函數(shù),所以對于兩個文件相同的數(shù)據(jù),經(jīng)過切分后,一定會在編號相同的桶中.

然后再利用哈希表或set都可以,先將一個文件全部插入,經(jīng)過去重后,再用另一個文件進行比對,找出交集即可。

?文章來源地址http://www.zghlxwxcb.cn/news/detail-525634.html

到了這里,關于哈希與位圖的結合--布隆過濾器與哈希切分的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 【數(shù)據(jù)結構與算法】哈?!?位圖 | 布隆過濾器 | 哈希切割

    【數(shù)據(jù)結構與算法】哈希—— 位圖 | 布隆過濾器 | 哈希切割

    ??作者:一只大喵咪1201 ??專欄:《數(shù)據(jù)結構與算法》 ??格言: 你只管努力,剩下的交給時間! 哈希是一種映射思想,這里再講解兩種應用哈希思想的數(shù)據(jù)結構。 問題: 給40億個不重復的無符號整數(shù),沒排過序。給一個無符號整數(shù),如何快速判斷一個數(shù)是否在這40億個數(shù)

    2024年02月02日
    瀏覽(25)
  • C++:布隆過濾器和哈希切分

    C++:布隆過濾器和哈希切分

    目錄 一.?什么是布隆過濾器 二.?布隆過濾器的實現(xiàn) 2.1?數(shù)據(jù)插入函數(shù)set 2.2?判斷數(shù)據(jù)是否存在函數(shù)test 2.3?布隆過濾器數(shù)據(jù)的刪除 三.?哈希切分 在我之前的博客C++:使用位圖處理海量數(shù)據(jù)_【Shine】光芒的博客-CSDN博客中,介紹了如何使用位圖來處理海量數(shù)據(jù),位圖的特點為:

    2024年02月09日
    瀏覽(28)
  • 【C++】哈希(位圖,布隆過濾器)

    【C++】哈希(位圖,布隆過濾器)

    今天的內(nèi)容是哈希的應用:位圖和布隆過濾器 目錄 一、位圖 1.位圖概念 2.位圖的應用 二、哈希切分 三、布隆過濾器 1.布隆過濾器的概念 2.布隆過濾器的應用 四、總結 ? 今天的內(nèi)容從一道面試題開始引入: 給40億個不重復的無符號整數(shù),沒排過序。給一個無符號整數(shù),如何

    2024年02月01日
    瀏覽(28)
  • C++哈希應用——位圖布隆過濾器

    C++哈希應用——位圖布隆過濾器

    用哈希表存儲用戶記錄,缺點是需要消耗較大的內(nèi)存;用位圖存儲用戶記錄,缺點是位圖一般處理整形,內(nèi)容是字符串或者自定義類型就很勉強?;谝陨希魧⒐:臀粓D結合,稱為布隆過濾器,會不會把上面的問題都解決了呢? 概念 布隆過濾器是一種概率型數(shù)據(jù)結構。

    2024年02月04日
    瀏覽(46)
  • 【C++】哈希位圖和布隆過濾器

    【C++】哈希位圖和布隆過濾器

    哈希位圖和布隆過濾器都是常用的概率數(shù)據(jù)結構,用于高效地判斷一個元素是否存在于一個集合當中,但它們在實現(xiàn)方法和各自的優(yōu)缺點上有所區(qū)別。 哈希位圖 哈希位圖(Hash Bitmap)是由一個位數(shù)組構成,每個元素(通常是一個整數(shù))被映射到位數(shù)組中的某個位置。對于集合

    2024年02月08日
    瀏覽(24)
  • 哈希的應用--位圖和布隆過濾器

    哈希的應用--位圖和布隆過濾器

    位圖(Bitset)是一種數(shù)據(jù)結構,用于表示一組布爾值,其中每個元素通常對應于一個位或一個二進制值,可以存儲0或1。位圖在計算機科學和計算機工程中經(jīng)常用于各種應用,特別是在位級別的標志、掩碼和快速查找中。以下是位圖的一些關鍵特點: 二進制表示 :位圖中的每

    2024年02月08日
    瀏覽(32)
  • [C++]哈希應用之位圖&布隆過濾器

    [C++]哈希應用之位圖&布隆過濾器

    ? ? ? ? ?? 主廚:邪王真眼 主廚的主頁:Chef‘s blog?? 所屬專欄:c++大冒險 ? ? ? ?我們之前學習了哈希表,哈希表通過映射關系,實現(xiàn)了O(1)的復雜度來查找數(shù)據(jù),哈希在實踐中是一個非常重要的思想,今天要學習的就是哈希思想的兩大應用:位圖與布隆過濾器 給 40 億個

    2024年04月15日
    瀏覽(36)
  • 【C++學習】哈希的應用—位圖與布隆過濾器

    【C++學習】哈希的應用—位圖與布隆過濾器

    文章簡介 : 在這篇文章中,你會學習到關于哈希思想的最常見的兩個應用,也就是 位圖 與 布隆過濾器 , 文章會講解位圖和布隆過濾器的概念,底層實現(xiàn),對應的適應的場景,以及相關經(jīng)典 海量數(shù)據(jù)面試題 及解析。 所謂位圖,就是用每一位來存放某種狀態(tài),適用于 海量

    2024年04月14日
    瀏覽(51)
  • 【C++高階(六)】哈希的應用--位圖&布隆過濾器

    【C++高階(六)】哈希的應用--位圖&布隆過濾器

    ??博主CSDN主頁:杭電碼農(nóng)-NEO?? ? ?專欄分類:C++從入門到精通? ? ??代碼倉庫:NEO的學習日記?? ? ??關注我??帶你學習C++ ? ???? 哈希最常用的應用是unordered 系列的容器,但是當面對海量數(shù)據(jù) 如100億個數(shù)據(jù)中找有沒有100這 個數(shù)時,使用無序容器的話內(nèi)存放不下 所以哈希

    2024年02月05日
    瀏覽(37)
  • C++進階--哈希的應用之位圖和布隆過濾器

    C++進階--哈希的應用之位圖和布隆過濾器

    哈希是一種映射的思想。 先來看一道題:給40億個不重復的無符號整數(shù),沒排序過。給一個無符號整數(shù),如何 快速判斷 一個數(shù) 是否在 這40億個數(shù)中。 首先想到的解法可能有這幾種: 解法1 :遍歷40億個數(shù),O(N) 解法2 :先排序,快排O( N l o g 2 N Nlog_2N Nl o g 2 ? N ),再利

    2024年02月22日
    瀏覽(43)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包