溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

【干貨】位圖的實(shí)現(xiàn)與布隆過(guò)濾器

發(fā)布時(shí)間:2020-10-04 09:00:21 來(lái)源:網(wǎng)絡(luò) 閱讀:708 作者:pawnsir 欄目:編程語(yǔ)言

    位圖是用一個(gè)btye位來(lái)表示一個(gè)數(shù)據(jù)是否存在,再通過(guò)哈希函數(shù)確定一個(gè)數(shù)據(jù)所在的位置,這樣處理會(huì)使當(dāng)僅需要判斷一個(gè)數(shù)據(jù)在不在的時(shí)候大大的提高效率,縮小內(nèi)存的使用,如一個(gè)數(shù)據(jù)為int型,而一個(gè)int型的數(shù)據(jù)構(gòu)成的位圖能表示32個(gè)數(shù)據(jù)的存在狀態(tài)。代碼實(shí)現(xiàn)如下:

Bitmap.h:

#include<vector>
class BitMap
{
public:
	BitMap(size_t size)
		:_size(0)
	{
		Size(size);
	}
	void Set(size_t key)
	{
		size_t index = key / 32;
		size_t offset = key % 32;
		_map[index]=_map[index] | (1 << offset);
		++_size;
	}
	void Reset(size_t key)
	{
		size_t index = key / 32;
		size_t offset = key % 32;
		if ((_map[index] >> offset) & 1)
		{
			_map[index] = _map[index] & (~(1 << offset));
			++_size;
		}
	}
	void Size(size_t size)
	{
		_map.resize(size);
	}
	bool Touch(size_t key)
	{
		size_t index = key / 32;
		size_t offset = key % 32;
		if ((_map[index] >> offset) & 1)
			return true;
		return false;
	}
protected:
	size_t _size;
	vector<size_t> _map;
};

    布隆過(guò)濾器布隆過(guò)濾器(Bloom Filter)是1970年由布隆提出的。它實(shí)際上是一個(gè)很長(zhǎng)的二進(jìn)制向量和一系列隨機(jī)映射函數(shù)。布隆過(guò)濾器可以用于檢索一個(gè)元素是否在一個(gè)集合中。它的優(yōu)點(diǎn)是空間效率和查詢(xún)時(shí)間都遠(yuǎn)遠(yuǎn)超過(guò)一般的算法,缺點(diǎn)是有一定的誤識(shí)別率和刪除困難。(百度百科)

    這里所說(shuō)的映射函數(shù)我們一般定義幾個(gè),這樣就可以加大避免沖突的幾率,這里我寫(xiě)了個(gè)key為string 類(lèi)的布隆過(guò)濾器,僅供參考:

BloomFilter.h:

#include"BitMap.h"
size_t BKDRHash(const char *str)//這里定義了5個(gè)映射算法,僅供參考
{
	register size_t hash = 0;
	while (size_t ch = (size_t)*str++)
	{
		hash = hash * 131 + ch;           
	}
	return hash;
}
size_t SDBMHash(const char *str)
{
	register size_t hash = 0;
	while (size_t ch = (size_t)*str++)
	{
		hash = 65599 * hash + ch;
		//hash = (size_t)ch + (hash << 6) + (hash << 16) - hash;  
	}
	return hash;
}

size_t RSHash(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 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;
}
size_t JSHash(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;
}
class BloomFilter
{
public:
	BloomFilter(size_t size)
		:_capacity(size)
		, map(size)
	{}
	void Set(const string &key)
	{
		size_t index1 = BKDRHash(key.c_str())%_capacity;
		size_t index2 = SDBMHash(key.c_str()) % _capacity;
		size_t index3 = RSHash(key.c_str()) % _capacity;
		size_t index4 = APHash(key.c_str()) % _capacity;
		size_t index5 = JSHash(key.c_str()) % _capacity;
		map.Set(index1);
		map.Set(index2);
		map.Set(index3);
		map.Set(index4);
		map.Set(index5);
	}
	bool Touch(const string &key)
	{
		if (!map.Touch(BKDRHash(key.c_str()) % _capacity))
			return false;
		if (!map.Touch(SDBMHash(key.c_str()) % _capacity))
			return false;
		if (!map.Touch(RSHash(key.c_str()) % _capacity))
			return false;
		if (!map.Touch(APHash(key.c_str()) % _capacity))
			return false;
		if (!map.Touch(JSHash(key.c_str()) % _capacity))
			return false;
		return true;
	}
protected:
	size_t _capacity;
	BitMap map;
};

    如有疑問(wèn)希望提出,有錯(cuò)誤希望指正

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI