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

C++哈希hash:位圖、布隆過濾器的實(shí)現(xiàn)及應(yīng)用

這篇具有很好參考價值的文章主要介紹了C++哈希hash:位圖、布隆過濾器的實(shí)現(xiàn)及應(yīng)用。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、位圖實(shí)現(xiàn)

1.1位圖的原理

所謂位圖,就是用每一位來存放某種狀態(tài),適用于海量數(shù)據(jù),數(shù)據(jù)無重復(fù)的場景。通常是用
來判斷某個數(shù)據(jù)存不存在的。 當(dāng)我們想查找某一個數(shù)據(jù)是否存在或者是否處于某種狀態(tài)時,相比于直接對存放數(shù)據(jù)的容器進(jìn)行遍歷查找,與原存放數(shù)據(jù)的容器所建立映射關(guān)系的位圖來進(jìn)行位運(yùn)算所查找的方式相比,很明顯是位圖更加快速便捷的。
這里首先實(shí)現(xiàn)了單個位圖的增刪查,然后以其為基礎(chǔ)構(gòu)造出一個內(nèi)部包含兩個位圖用于允許一個位置被映射多次的two_bit_set。
#pragma once
#include<iostream>
#include<vector>
#include<assert.h>
using namespace std;
namespace gazbitset
{
	template<size_t N>
	class bitset
	{
	public:
		bitset()
		{
			_bits.resize(N/32+1,0);
		}
		//將x映射的位置標(biāo)記成1
		void set(size_t x)
		{
			assert(x <= N);
			size_t i = x / 32;
			size_t j = x % 32;
			_bits[i] |= (1 << j);
		}
		// 把x映射的位標(biāo)記成0
		void reset(size_t x)
		{
			assert(x <= N);

			size_t i = x / 32;
			size_t j = x % 32;

			_bits[i] &= ~(1 << j);
		}
		//查找一個值是否在位圖中,在就返回1,不在返回0
		bool test(size_t x)
		{
			assert(x <= N);
			size_t i = x / 32;
			size_t j = x % 32;
			return _bits[i] & (1 << j);
		}
	private:
		vector<int> _bits;
	};

	template<size_t N>
	class two_bit_set
	{
	public:
		void set(size_t x)
		{
			if (b1.test(x) == false && b2.test(x) == false)
			{
				b2.set(x);
			}
			else if (b1.test(x) == false && b2.test(x) == true)
			{
				b1.set(x);
				b2.reset(x);
			}
		}
		//檢測只出現(xiàn)一次的數(shù)
		bool testone(size_t x)
		{
			if (b1.test(x) == false && b2.test(x)==true)
			{
				return true;
			}
			return false;
		}
	private:
		bitset<N> b1;
		bitset<N> b2;
	};
}

1.2位圖應(yīng)用

1. 快速查找某個數(shù)據(jù)是否在一個集合中。
2. 排序 + 去重。
3. 求兩個集合的交集、并集等。
4. 操作系統(tǒng)中磁盤塊標(biāo)記。

二、布隆過濾器

當(dāng)我們在各大游戲或社交平臺注冊賬號時,有的平臺昵稱往往是不允許重復(fù)的,那當(dāng)輸入昵稱時,系統(tǒng)是如何立馬就能進(jìn)行判斷查找出是否存在重復(fù)的呢?

根據(jù)所學(xué)知識,通??梢韵氲絻煞N方法:

1. 用哈希表存儲用戶記錄,缺點(diǎn):浪費(fèi)空間
2. 用位圖存儲用戶記錄,缺點(diǎn):位圖一般只能處理整形,如果內(nèi)容編號是字符串,就無法處理
了。
兩種方法各有優(yōu)缺,但如果將哈希和位圖結(jié)合起來,就可以完美的解決此問題,此時就可以得到一種全新的結(jié)構(gòu):布隆過濾器。
布隆過濾器概念
布隆過濾器是由布?。˙urton Howard Bloom)在1970年提出的 一種緊湊型的、比較巧妙的概率型數(shù)據(jù)結(jié)構(gòu),特點(diǎn)是高效地插入和查詢,可以用來告訴你 “某樣?xùn)|西一定不存在或者可能存在”,它是用多個哈希函數(shù),將一個數(shù)據(jù)映射到位圖結(jié)構(gòu)中。此種方式不僅可以提升查詢效率,也可以節(jié)省大量的內(nèi)存空間
C++哈希hash:位圖、布隆過濾器的實(shí)現(xiàn)及應(yīng)用,C/C++,數(shù)據(jù)結(jié)構(gòu),c++,哈希算法,開發(fā)語言

?2.1布隆過濾器的原理

講述布隆過濾器的原理之前,我們先思考一下,通常你判斷某個元素是否存在用的是什么?應(yīng)該大多數(shù)人會回答 HashMap 吧,確實(shí)可以將值映射到 HashMap 的 Key,然后可以在 O(1) 的時間復(fù)雜度內(nèi)返回結(jié)果,效率奇高。但是 HashMap 的實(shí)現(xiàn)也有缺點(diǎn),例如存儲容量占比高,考慮到負(fù)載因子的存在,通??臻g是不能被用滿的,而一旦你的值很多例如上億的時候,那 HashMap 占據(jù)的內(nèi)存大小就變得很可觀了。

還比如說你的數(shù)據(jù)集存儲在遠(yuǎn)程服務(wù)器上,本地服務(wù)接受輸入,而數(shù)據(jù)集非常大不可能一次性讀進(jìn)內(nèi)存構(gòu)建 HashMap 的時候,也會存在問題。

2.2布隆過濾器的查找

C++哈希hash:位圖、布隆過濾器的實(shí)現(xiàn)及應(yīng)用,C/C++,數(shù)據(jù)結(jié)構(gòu),c++,哈希算法,開發(fā)語言

?布隆過濾器是一個 bit 向量或者說 bit 數(shù)組,如果我們要映射一個值到布隆過濾器中,我們需要使用多個不同的哈希函數(shù)生成多個哈希值,并對每個生成的哈希值指向的 bit 位置 1,例如針對值 “C+五條” 通過三個不同的哈希函數(shù)分別生成了哈希值 1、4、7,則上圖轉(zhuǎn)變?yōu)椋?/span>

C++哈希hash:位圖、布隆過濾器的實(shí)現(xiàn)及應(yīng)用,C/C++,數(shù)據(jù)結(jié)構(gòu),c++,哈希算法,開發(fā)語言

我們現(xiàn)在再存一個值 “CSDN”,如果哈希函數(shù)返回 3、4、8 的話,圖繼續(xù)變?yōu)椋?

C++哈希hash:位圖、布隆過濾器的實(shí)現(xiàn)及應(yīng)用,C/C++,數(shù)據(jù)結(jié)構(gòu),c++,哈希算法,開發(fā)語言

值得注意的是,4 這個 bit 位由于兩個值的哈希函數(shù)都返回了這個 bit 位,因此它被覆蓋了。現(xiàn)在我們?nèi)绻氩樵?“dianping” 這個值是否存在,哈希函數(shù)返回了 1、5、8三個值,結(jié)果我們發(fā)現(xiàn) 5 這個 bit 位上的值為 0,說明沒有任何一個值映射到這個 bit 位上,因此我們可以很確定地說 “dianping” 這個值不存在。而當(dāng)我們需要查詢 “C+五條” 這個值是否存在的話,那么哈希函數(shù)必然會返回 1、4、7,然后我們檢查發(fā)現(xiàn)這三個 bit 位上的值均為 1,那么我們可以說 “C+五條”?存在了么?答案是不可以,只能是 “C+五條” 這個值可能存在。

這是為什么呢?答案跟簡單,因?yàn)殡S著增加的值越來越多,被置為 1 的 bit 位也會越來越多,這樣某個值 “taobao” 即使沒有被存儲過,但是萬一哈希函數(shù)返回的三個 bit 位都被其他值置位了 1 ,那么程序還是會判斷 “taobao” 這個值存在。

注意:布隆過濾器如果說某個元素不存在時,該元素一定不存在,如果該元素存在時,該元素可
能存在,因?yàn)橛行┕:瘮?shù)存在一定的誤判。

2.2布隆過濾器的刪除

布隆過濾器不能直接支持刪除工作,因?yàn)樵趧h除一個元素時,可能會影響其他元素。
比如:刪除上圖中"tencent"元素,如果直接將該元素所對應(yīng)的二進(jìn)制比特位置0,“baidu”元素也被
刪除了,因?yàn)檫@兩個元素在多個哈希函數(shù)計(jì)算出的比特位上剛好有重疊。
一種支持刪除的方法:將布隆過濾器中的每個比特位擴(kuò)展成一個小的計(jì)數(shù)器,插入元素時給k個計(jì)
數(shù)器(k個哈希函數(shù)計(jì)算出的哈希地址)加一,刪除元素時,給k個計(jì)數(shù)器減一,通過多占用幾倍存儲
空間的代價來增加刪除操作。
缺陷
1. 無法確認(rèn)元素是否真正在布隆過濾器中
2. 存在計(jì)數(shù)回繞

2.3如何選擇哈希函數(shù)個數(shù)和布隆過濾器長度

很顯然,過小的布隆過濾器很快所有的 bit 位均為 1,那么查詢?nèi)魏沃刀紩祷亍翱赡艽嬖凇保鸩坏竭^濾的目的了。布隆過濾器的長度會直接影響誤報(bào)率,布隆過濾器越長其誤報(bào)率越小。

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

C++哈希hash:位圖、布隆過濾器的實(shí)現(xiàn)及應(yīng)用,C/C++,數(shù)據(jù)結(jié)構(gòu),c++,哈希算法,開發(fā)語言

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

三、布隆過濾器的實(shí)現(xiàn)

#pragma once
#include<bitset>
#include<string>
#include<iostream>
using namespace std;
struct HashFuncBKDR//第一個哈希函數(shù)
{
	// BKDR
	size_t operator()(const string& s)
	{
		size_t hash = 0;
		for (auto ch : s)
		{
			hash *= 131;
			hash += ch;
		}

		return hash;
	}
};

struct HashFuncAP//第二個哈希函數(shù)
{
	// AP
	size_t operator()(const string& s)
	{
		size_t hash = 0;
		for (size_t i = 0; i < s.size(); i++)
		{
			if ((i & 1) == 0) // 偶數(shù)位字符
			{
				hash ^= ((hash << 7) ^ (s[i]) ^ (hash >> 3));
			}
			else              // 奇數(shù)位字符
			{
				hash ^= (~((hash << 11) ^ (s[i]) ^ (hash >> 5)));
			}
		}

		return hash;
	}
};

struct HashFuncDJB//第三個哈希函數(shù)
{
	// DJB
	size_t operator()(const string& s)
	{
		size_t hash = 5381;
		for (auto ch : s)
		{
			hash = hash * 33 ^ ch;
		}

		return hash;
	}
};

template<size_t N,
	class K=string,
	class Hash1 = HashFuncBKDR,
	class Hash2 = HashFuncAP,
	class Hash3 = HashFuncDJB>
class bloomfilter
{
public:
	void set(const K& key)
	{
		size_t hash1 = Hash1()(key) % M;
		size_t hash2 = Hash2()(key) % M;
		size_t hash3 = Hash3()(key) % M;

		_bs->set(hash1);
		_bs->set(hash2);
		_bs->set(hash3);
	}
	bool Test(const K& key)
	{
		size_t hash1 = Hash1()(key) % M;
		if (_bs->test(hash1) == false)
			return false;
		size_t hash2 = Hash2()(key) % M;
		if (_bs->test(hash2) == false)
			return false;

		size_t hash3 = Hash3()(key) % M;
		if (_bs->test(hash3) == false)
			return false;

		return true; // 存在誤判(有可能3個位都是跟別人沖突的,所以誤判)
	}
private:
	static const size_t M = 10 * N;
	std::bitset<M>* _bs = new std::bitset<M>;
};

布隆過濾器的優(yōu)缺點(diǎn)

優(yōu)點(diǎn):文章來源地址http://www.zghlxwxcb.cn/news/detail-848089.html

1. 增加和查詢元素的時間復(fù)雜度為:O(K), (K為哈希函數(shù)的個數(shù),一般比較小),與數(shù)據(jù)量大小無關(guān)。
2. 哈希函數(shù)相互之間沒有關(guān)系,方便硬件并行運(yùn)算。
3.布隆過濾器不需要存儲元素本身,在某些對保密要求比較嚴(yán)格的場合有很大優(yōu)勢。
4.在能夠承受一定的誤判時,布隆過濾器比其他數(shù)據(jù)結(jié)構(gòu)有這很大的空間優(yōu)勢。
5. 數(shù)據(jù)量很大時,布隆過濾器可以表示全集,其他數(shù)據(jù)結(jié)構(gòu)不能。
6. 使用同一組散列函數(shù)的布隆過濾器可以進(jìn)行交、并、差運(yùn)算。
缺點(diǎn):
1. 有誤判率,即存在假陽性(False Position),即不能準(zhǔn)確判斷元素是否在集合中(補(bǔ)救方法:再
建立一個白名單,存儲可能會誤判的數(shù)據(jù))。
2. 不能獲取元素本身。
3. 一般情況下不能從布隆過濾器中刪除元素 。
4. 如果采用計(jì)數(shù)方式刪除,可能會存在計(jì)數(shù)回繞問題。

到了這里,關(guān)于C++哈希hash:位圖、布隆過濾器的實(shí)現(xiàn)及應(yīng)用的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • C++ 哈希思想應(yīng)用:位圖,布隆過濾器,哈希切分

    C++ 哈希思想應(yīng)用:位圖,布隆過濾器,哈希切分

    1.問題 給你40億個不重復(fù)的無符號整數(shù),沒排過序.給一個無符號整數(shù),如何快速判斷一個數(shù)是否在這40億個數(shù)中? 2.分析 1 Byte = 8 bit 1KB = 1024 Byte 1MB = 1024KB = 1024 1024 大約= 10的6次方Byte 1GB = 1024MB = 1024 10的6次方 大約= 10的9次方Byte = 10億字節(jié) 因此4GB 約等于40億字節(jié) 其實(shí)最快的方式就是

    2024年04月17日
    瀏覽(41)
  • [C++]哈希應(yīng)用之位圖&布隆過濾器

    [C++]哈希應(yīng)用之位圖&布隆過濾器

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

    2024年04月15日
    瀏覽(35)
  • 【C++】哈希的應(yīng)用:位圖、哈希切分與布隆過濾器

    【C++】哈希的應(yīng)用:位圖、哈希切分與布隆過濾器

    需要云服務(wù)器等云產(chǎn)品來學(xué)習(xí)Linux的同學(xué)可以移步/--騰訊云--/--阿里云--/--華為云--/官網(wǎng),輕量型云服務(wù)器低至112元/年,新用戶首次下單享超低折扣。 ? 目錄 一、位圖 1、位圖的概念 2、大廠面試題 2.1位圖應(yīng)用(騰訊) 2.2位圖應(yīng)用 3、位圖的優(yōu)缺點(diǎn) 二、哈希切分 三、布隆過濾

    2023年04月09日
    瀏覽(39)
  • 【C++高階(六)】哈希的應(yīng)用--位圖&布隆過濾器

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

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

    2024年02月05日
    瀏覽(36)
  • 【C++學(xué)習(xí)】哈希的應(yīng)用—位圖與布隆過濾器

    【C++學(xué)習(xí)】哈希的應(yīng)用—位圖與布隆過濾器

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

    2024年04月14日
    瀏覽(51)
  • C++進(jìn)階--哈希的應(yīng)用之位圖和布隆過濾器

    C++進(jìn)階--哈希的應(yīng)用之位圖和布隆過濾器

    哈希是一種映射的思想。 先來看一道題:給40億個不重復(fù)的無符號整數(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)
  • 【C++雜貨鋪】再談哈希算法:位圖 | 布隆過濾器 | 哈希切分

    【C++雜貨鋪】再談哈希算法:位圖 | 布隆過濾器 | 哈希切分

    給40億個不重復(fù)的無符號整數(shù),沒排過序。給一個無符號整數(shù),如何快速判斷一個數(shù)是否在這40億個數(shù)中。 解決方案 : 遍歷 :遍歷這40億個整數(shù),去判斷該數(shù)是否在這40億個整數(shù)中。時間復(fù)雜度是 O ( N ) O(N) O ( N ) 。 set :用 set 將這40億個整數(shù)存起來,然后去判斷這個數(shù)是否在

    2024年02月08日
    瀏覽(30)
  • 哈希思想應(yīng)用【C++】(位圖,布隆過濾器,海量數(shù)據(jù)處理面試題)

    哈希思想應(yīng)用【C++】(位圖,布隆過濾器,海量數(shù)據(jù)處理面試題)

    ?? 目錄 一,位圖 1. 位圖概念 2.實(shí)現(xiàn) 3. 測試題 位圖的優(yōu)缺點(diǎn) 二,布隆過濾器 1). 布隆過濾器提出 2). 概念 3). 布隆過濾器的查找 4). 布隆過濾器刪除(了解) 5). 布隆過濾器優(yōu)點(diǎn) 6).?布隆過濾器缺陷 三,海量數(shù)據(jù)面試題 1)哈希切割 我們首先由一道面試題來理解位圖 給40億個不

    2024年02月04日
    瀏覽(50)
  • C++ 哈希+unordered_map+unordered_set+位圖+布隆過濾器(深度剖析)

    C++ 哈希+unordered_map+unordered_set+位圖+布隆過濾器(深度剖析)

    想象一下,你有一個巨大的圖書館,里面擺滿了成千上萬本書。如果你想要找到其中一本特定的書,你會怎么做?如果你按照書的編號來有序地排列它們,找到特定的書本可能會很容易。但是,如果書籍是隨機(jī)地?cái)[放,你可能需要逐本地查找,這個過程會非常耗時。 而哈希函

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

    哈希的應(yīng)用--位圖和布隆過濾器

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

    2024年02月08日
    瀏覽(31)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包