【C++】海量数据处理面试题(位图和布隆过滤器)

这篇具有很好参考价值的文章主要介绍了【C++】海量数据处理面试题(位图和布隆过滤器)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

都是大厂面试题哦~

文章目录

  • 一.位图面试题
  •     1.给定100亿个整数,设计算法找到只出现一次的整数
  •     2.给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集?
  •     3.1个文件有100亿个int1G内存,设计算法找到出现次数不超过2次的所有整
  • 二.布隆过滤器
  • 总结

一、位图面试题

40 亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在
40 亿个数中。【腾讯】
1.遍历,时间复杂度为O(N)
2.排序(NlogN),二分查找(logN)
3.位图。时间复杂度O(1)
下面我们先讲解一下题目,首先我们要判断一个数是否存在,那么这个数只需要有两种状态即可,要不存在,要不就是不存在,而比特位中0和1就能表示存在和不存在两种状态,所以我们用一个char类型就能判断8个值是否存在(因为一字节有8个bit位),现在我们分析一下题目,首先40亿个无符号整数是多大呢我们算一下:一个整数是4字节,40*4=160亿字节,1G = 1024*1024*1024大约10亿字节,1G是10亿字节那么160亿字节就是16G,这么大的内存仅仅是为了判断某个数存不存在也太浪费了,那么我们再算算位图需要耗费多少内存:一个char可以判断8个数是否存在,所以仅需40亿/8=5亿个char就能判断40亿个数,一个char是1字节,5亿个char就是5亿字节,10亿字节是1G,5亿字节是512MB,从刚刚需要16G内存到现在512MB内存就能搞定,面试官一定会对你刮目相看的。
下面我们画图分析一下位图的原理:
【C++】海量数据处理面试题(位图和布隆过滤器)

如上图理解了位图的原理我们现在就开始实现吧:

namespace sxy
{
	template <size_t N>
	class biteset
	{
	public:
		biteset()
		{
			_bits.resize(N / 8 + 1, 0);
		}
	private:
		vector<char> _bits;
	};
}

 首先我们先将大致的框架写出来,N这个模板参数是我们要开多少个比特位,然后我们直接用vector来实现,vector中存char类型,一个char是8个比特位,当用户想要10个比特位的时候我们应该开几个char呢?很明显如果仅仅10/8算出来1个char是不够的,所以我们需要多开一个防止不能整除的情况,然后记得将每个char初始化为0,这样每个比特位都是0了。

//将某个数映射为比特位将那个比特位置为1
		void set(size_t x)
		{
			size_t i = x / 8;
			size_t j = x % 8;
			_bits[i] |= (1 << j);
		}
		//将某个数的比特位重新置为0
		void reset(size_t x)
		{
			size_t i = x / 8;
			size_t j = x % 8;
			_bits[i] &= ~(1 << j);
		}
首先我们看set,将某个比特位设置为1很简单,我们只需要让1左移j个比特位然后或上那个位置的char,为什么是或呢?要注意L我们进行某个位的运算是不能改变其他位的,比如我们要修改第2个比特位结果把第5个也修改了,那么一定是错了,让其按位或1如下图:
【C++】海量数据处理面试题(位图和布隆过滤器)

上图中以10这个数演示,最后的结果变成了0 1 0 0 0 1 0 0  既没有改变原先第6个比特位的1又改变了第2个比特位将10这个数表示出来了,所以我们的代码是正确的。

下面看reset函数:

【C++】海量数据处理面试题(位图和布隆过滤器)

如果对于位运算不懂得还是先去看看位运算-.-。

下面我们用test函数来测试一个数是否存在:

bool test(size_t x)
		{
			size_t i = x / 8;
			size_t j = x % 8;
			return _bits[i] & (1 << j);
		}

 这里要注意我们只是检查某个数是否存在,不能改变原来的位图所以不是&=,注意我们的返回值是bool型,如果返回值不为0说明那个比特位为1就是存在,否则就是不存在。

当然我们也可以写一个看位图中记录多少个存在的数的函数,不过这个函数与本题无关罢了:

	//位图中有映射了多少个数
		size_t Count()
		{
			size_t count = 0;
			for (size_t i = 0; i < _bits.size(); i++)
			{
				int j = 0;
				while (j < 8)
				{
					if (_bits[i] & (1 << j))
					{
						++count;
					}
					++j;
				}
			}
			return count;
		}

只需要让1依次为每个char的比特位按位与一遍,不为0的就是1让计数器++即可。

 下面我们测试一下:

void testbit()
	{
		//-1给无符号就是整形的最大值,开500多MB内存
		biteset<200> bt;
		bt.set(10);
		cout << bt.test(10) << endl;
		bt.reset(10);
		cout << bt.test(10) << endl;
		/*bt.set(11);
		bt.set(12);
		bt.set(13);
		bt.set(19);
		bt.set(46);
		bt.set(75);
		cout << bt.Count() << endl;*/
	}

【C++】海量数据处理面试题(位图和布隆过滤器)

 运行没问题我们在看看内存中的值:

【C++】海量数据处理面试题(位图和布隆过滤器)

【C++】海量数据处理面试题(位图和布隆过滤器)

【C++】海量数据处理面试题(位图和布隆过滤器) 可以看到刚开始设置的时候确实将char的第2个比特位改为1了,因为内存中是16进制,所以

0000 0100在内存显示 :0  4 然后reset的时候又改回了00.下面我们多放几个值测试一下:

【C++】海量数据处理面试题(位图和布隆过滤器)

 也是没问题的,这里我们讲一下如何开最大整形的比特位,我们的N是size_t无符号整数,当我们传-1时那么就是整形的最大值,如下图:

【C++】海量数据处理面试题(位图和布隆过滤器)

1.给定100亿个整数,设计算法找到只出现一次的整数?

其实很简单,还是我们刚刚的位图,只需要变形一下。我们用两个位图,这样每个值就有两个比特位来表示,00表示0次,01表示1次,10表示多次,然后没有其他情况,下面我们实现一下:

template <size_t N>
	class two_biteset
	{
	public:
		void set(size_t x)
		{
			//如果这个值没有被映射过
			if (_bs1.test(x) == false && _bs2.test(x) == false)
			{
				// 00    我们以bs1代表左边那个0,bs2代表右边那个0
				//要想00->01  只需要让s2变1
				_bs2.set(x);
			}
			//如果这个值被映射过1次 01
			else if (_bs1.test(x) == false && _bs2.test(x) == true)
			{
				//将1次改为多次,多次用10表示  01->10
				_bs1.set(x);
				_bs2.reset(x);
			}
		}
		//打印出现1次的数
		void print()
		{
			for (size_t i = 0; i < N; i++)
			{
				if (_bs2.test(i) == true)
				{
					cout << i << " ";
				}
			}
			cout << endl;
		}
	private:
		biteset<N> _bs1;
		biteset<N> _bs2;
	};

我们直接复用刚刚的位图结构,代码中我们已经注释过了,需要注意的是,当用户开100个比特位时,那么要set的数一定是在0-100这个区间内的,超出这个区间的数算出来的第多少个char是越界的,所以我们打印的时候按照范围0-N即可。下面测试一下:

void test_twobite()
	{
		int a[] = { 1,1,4,4,89,95,45,45,65,65,25,25 };
		two_biteset<100> bt;
		for (auto& e : a)
		{
			bt.set(e);
		}
		bt.print();
	}

【C++】海量数据处理面试题(位图和布隆过滤器)

 可以看到并没有问题,这样就解决了100亿个整数找出只出现1次的数的问题了。

 2.给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集?

两个文件,100亿整数是400亿字节,也就是40G,两个40G的文件如何找交集呢?

1.将一个文件的数据映射到位图中,然后遍历第二个文件,判断第二个文件中的数是否在位图中存在,如果存在就是交集。当然有可能发生:第一个文件{1,3,4},第二个文件{1,1,3,4,4},这个时候判断出来的交集是{1,1,3,4,4,}也就是会有重复的值,所以我们可以再去一次重。当然也可以不去重,直接看是否存在,存在就保存这个交集中的值然后将这个值映射的比特位置为0,这样下面的重复值就不会被保存。

2.将两个文件分别映射到两个位图中,这样做可以直接去除两个文件中的重复值。然后范围遍历,两个位图中某个数都为true则这个数就是交集,代码如下:

for (size_t i = 0;i<N;i++)

     if (bs1.test(i)==true&&bs2.test(i)==true)

    {

             //则是交集

    }

}

3. 1个文件有100亿个int1G内存,设计算法找到出现次数不超过2次的所有整数

不超过两次的整数就是1次和2次,所以我们将上面的代码修改一下,让10表示2次,11表示多次。

template <size_t N>
	class three_biteset
	{
	public:
		void set(size_t x)
		{
			//如果这个值没有被映射过
			if (_bs1.test(x) == false && _bs2.test(x) == false)
			{
				// 00    我们以bs1代表左边那个0,bs2代表右边那个0
				//要想00->01  只需要让s2变1
				_bs2.set(x);
			}
			//如果这个值被映射过1次 01
			else if (_bs1.test(x) == false && _bs2.test(x) == true)
			{
				//将1次改为2次,2次用10表示  01->10
				_bs1.set(x);
				_bs2.reset(x);
			}
			else
			{
				//多次用11表示
				_bs1.set(x);
				_bs2.set(x);
			}
		}
		void print()
		{
			for (size_t i = 0; i < N; i++)
			{
				if (_bs1.test(i) == true && _bs2.test(i) == false
					|| _bs1.test(i) == false && _bs2.test(i) == true)
				{
					cout << i << " ";
				}
			}
			cout << endl;
		}
	private:
		biteset<N> _bs1;
		biteset<N> _bs2;
	};
下面我们测试一下:
void test_threebite()
	{
		int a[] = { 1,1,1,4,4,4,89,95,45,45,45,65,65,65,25,25,25,45 };
		three_biteset<100> bt;
		for (auto& e : a)
		{
			bt.set(e);
		}
		bt.print();
	}

【C++】海量数据处理面试题(位图和布隆过滤器)

我们总结一下位图的优缺点:

优点:速度快,节省空间

缺点:只能映射整形,其他类型如:浮点数,string等等不能存储映射。

 二、布隆过滤器

布隆过滤器实际上就是位图和哈希的组合,位图只能处理整形处理不了字符串,而布隆过滤器可以映射字符串,如下图(图片是转载):

【C++】海量数据处理面试题(位图和布隆过滤器)

 这个时候向布隆过滤器插入“baidu”:

【C++】海量数据处理面试题(位图和布隆过滤器)

 也就是说我们让哈希函数将字符串进行转化,转化后将这个值映射到位图中,学过哈希我们都知道哈希冲突是解决不了的,所以一定会存在冲突问题(一个值映射一个位置有很大概率会冲突,一个值映射多个位置就可以减少冲突),为了避免冲突我们就引入多个哈希函数,让多个哈希函数将字符串转化后映射到不同的比特位。

了解了以上知识后问大家一个问题,布隆过滤器是判断在的时候会被冲突还是判断不在的时候会被冲突呢?这里一定是在的时候被冲突,如下图:

【C++】海量数据处理面试题(位图和布隆过滤器)

 现在有baidu和left两个字符串,如果有一个字符串hello计算出来的哈希值映射到位图中正好是baidu和left被置为1的位置,那么这个时候就会误判hello是存在,但实际上hello并不存在。所以布隆过滤器一定可以判断某个字符串不存在,而对于存在的情况会产生误判。所以布隆过滤器的使用场景是:能容忍误判的场景。比如:注册时快速判断昵称是否使用过

那么手机号码是否注册过可以用布隆过滤器判断吗?可以,但是一定要结合数据库。我们用布隆过滤器判断手机号码是否注册过,因为布隆过滤器判断不存在是准确的,所以如果不存在那么就一定没有注册过,如果判断存在我们就让其去数据库再判断一次,最后的结果是看数据库的结果,这样的效率比直接去数据库查找手机号码是否注册快了很多,因为数据库是在磁盘中存储的。

下面我们实现一下:

struct BKDRHash
{
	size_t operator()(const string& s)
	{
		size_t hash = 0;
		for (auto& e : s)
		{
			hash += e;
			hash *= 31;
		}
		return hash;
	}
};
struct APHash
{
    size_t operator()(const string& s)
    {
        size_t hash = 0;
        for (long i = 0; i < s.size(); i++)
        {
            size_t ch = s[i];
            if ((i & 1) == 0)
            {
                hash ^= ((hash << 7) ^ ch ^ (hash >> 3));
            }
            else
            {
                hash ^= (~((hash << 11) ^ ch ^ (hash >> 5)));
            }
        }
        return hash;
    }
};
struct DJBHash
{
    size_t operator()(const string& s)
    {
        size_t hash = 5381;
        for (auto ch : s)
        {
            hash += (hash << 5) + ch;
        }
        return hash;
    }
};
template <size_t N, class K = string,
	class Hash1 = BKDRHash,
	class Hash2 = APHash,
	class Hash3 = DJBHash>
class BloomFilter
{
public:
	void set(const K& key)
	{
        size_t hash1 = Hash1()(key) % N;
        //用第一个哈希函数映射位图
        _bs.set(hash1);
        size_t hash2 = Hash2()(key) % N;
        //用第二个哈希函数映射位图
        _bs.set(hash2);
        size_t hash3 = Hash3()(key) % N;
        //用第三个哈希函数映射位图
        _bs.set(hash3);
	}
    bool test(const K& key)
    {
        size_t hash1 = Hash1()(key) % N;
        if (_bs.test(hash1) == false)
        {
            return false;
        }
        size_t hash2 = Hash2()(key) % N;
        if (_bs.test(hash2) == false)
        {
            return false;
        }
        size_t hash3 = Hash3()(key) % N;
        if (_bs.test(hash3) == false)
        {
            return false;
        }
        return true;
    }
private:
	sxy::biteset<N> _bs;
};

首先模板参数中的N代表最多要插入多少个key数据的个数,K是存储数据的类型,然后就是3个哈希函数,当然也可以多来几个哈希函数。set也很简单,就是用哈希函数算出K类型的值然后去位图中映射,要注意的是我们每次算出来后都要对N进行一次取模。查找是否存在也很简单,只需要判断每一个哈希函数算出来的值映射的比特位是否为1,如果有一个为0那么一定不存在(这点我们上面说过,布隆过滤器判断不存在是准确的)。注意:布隆过滤器天生不支持删除,如果实现删除可以像我们用两个位图实现计数那样,要删除只需要--即可。

下面是哈希算法的网址:https://www.cnblogs.com/-clq/archive/2012/05/31/2528153.html

下面我们优化一下布隆过滤器:

【C++】海量数据处理面试题(位图和布隆过滤器)

 也就是说哈希函数的个数和N之间有一个关系,3 = (m/n)*0.69,然后同时除0.69得到m与n之间是4倍的关系。

【C++】海量数据处理面试题(位图和布隆过滤器)

void set(const K& key)
	{
        size_t len = N * _x;
        size_t hash1 = Hash1()(key) % len;
        //用第一个哈希函数映射位图
        _bs.set(hash1);
        size_t hash2 = Hash2()(key) % len;
        //用第二个哈希函数映射位图
        _bs.set(hash2);
        size_t hash3 = Hash3()(key) % len;
        //用第三个哈希函数映射位图
        _bs.set(hash3);
	}
    bool test(const K& key)
    {
        size_t len = N * _x;
        size_t hash1 = Hash1()(key) % len;
        if (_bs.test(hash1) == false)
        {
            return false;
        }
        size_t hash2 = Hash2()(key) % len;
        if (_bs.test(hash2) == false)
        {
            return false;
        }
        size_t hash3 = Hash3()(key) % len;
        if (_bs.test(hash3) == false)
        {
            return false;
        }
        return true;
    }

【C++】海量数据处理面试题(位图和布隆过滤器)

 下面我们打印哈希函数看一下冲突的情况:

void test_bloomfilter()
{
    BloomFilter<100> bf;
    bf.set("sort");
    bf.set("bloom");
    bf.set("hello world");
    bf.set("test");
    bf.set("etst");
    bf.set("estt");
}

【C++】海量数据处理面试题(位图和布隆过滤器)

 我们可以看到sort字符串的hash3这个值和bloom字符串的hash1冲突了都是相同的值,下面我们用一个测试用例来测试布隆过滤器发生冲突的百分比:

void test_bloomfilter2()
    {
        srand(time(0));
        const size_t N = 10000;
        BloomFilter<N> bf;
        std::vector<std::string> v1;
        std::string url = "https://www.cnblogs.com/-clq/archive/2012/05/31/2528153.html";
        for (size_t i = 0; i < N; ++i)
        {
            v1.push_back(url + std::to_string(i));
        }

        for (auto& str : v1)
        {
            bf.set(str);
        }

        // v2跟v1是相似字符串集,但是不一样
        std::vector<std::string> v2;
        for (size_t i = 0; i < N; ++i)
        {
            std::string url = "https://www.cnblogs.com/-clq/archive/2012/05/31/2528153.html";
            url += std::to_string(999999 + i);
            v2.push_back(url);
        }

        size_t n2 = 0;
        for (auto& str : v2)
        {
            if (bf.test(str))
            {
                ++n2;
            }
        }
        cout << "相似字符串误判率:" << (double)n2 / (double)N << endl;

        // 不相似字符串集
        std::vector<std::string> v3;
        for (size_t i = 0; i < N; ++i)
        {
            string url = "zhihu.com";
            //string url = "https://www.cctalk.com/m/statistics/live/16845432622875";
            url += std::to_string(i + rand());
            v3.push_back(url);
        }

        size_t n3 = 0;
        for (auto& str : v3)
        {
            if (bf.test(str))
            {
                ++n3;
            }
        }
        cout << "不相似字符串误判率:" << (double)n3 / (double)N << endl;
    }

 v1是字符串集,v2是v1的相似字符串集合,下面我们运行一下:

【C++】海量数据处理面试题(位图和布隆过滤器)

 测试后我们发现4倍的误判率在15%左右,下面我们换成5倍看看:

【C++】海量数据处理面试题(位图和布隆过滤器)

【C++】海量数据处理面试题(位图和布隆过滤器) 可以发现5倍时误判率下降到了%6,但这是用空间换来的,以上就是布隆过滤器,下面我们做两道面试题:

1. 给两个文件,分别有 100 亿个 query ,我们只有 1G 内存,如何找到两个文件交集?分别给出
精确算法和近似算法
query查询,本质query就是一个字符串,如:sql语句
100亿个query大概要占用多少空间?假设单个query平均50字节,100亿query就是5000亿字节,500G内存。两个这么大的文件如何找交集呢?近似算法:将每个文件都切成一个个的小文件,这里要用哈希切割,哈希切割:i = HashFunc(query)%1000,然后每个query算出的对应的i是多少就进入Ai号小文件,第二个文件同样的操作,然后我们根据算出的i编号让第一个文件中的小文件和第二个文件中的小文件找交集。但是这样会有个问题:因为不是平均切分,可能会出现冲突多,每个Ai,Bi小文件过大。我们将上面的问题分为两个情况:
1.单个文件中有某个大量重复的query。
2.单个文件中,有大量不同的query。
利用set/unordered_set去重,依次读取文件query,插入set中,1.如果读取整个小文件query,都可以成功插入set,那么说明是情况1.
如果读取整个小文件query,插入过程中抛异常,则是情况2,这种情况直接换其他的哈希函数再次分割,然后再求交集。什么意思呢,就是说:set插入key,如果已经有了就返回false,如果没有内存则会抛bad_alloc异常,剩下的都会成功。
2. 如何扩展 BloomFilter 使得它支持删除元素的操作

 我们之前用两个位图实现了计算数据1次两次或多次,如果要让布隆过滤器支持删除只需要把映射的值改为可以记录次数的,每次删除只需要--即可。文章来源地址https://www.toymoban.com/news/detail-469061.html


总结

布隆过滤器的查找
布隆过滤器的思想是将一个元素用多个哈希函数映射到一个位图中,因此被映射到的位置的比特
位一定为 1 。所以可以按照以下方式进行查找: 分别计算每个哈希值对应的比特位置存储的是否为
零,只要有一个为零,代表该元素一定不在哈希表中,否则可能在哈希表中
注意:布隆过滤器如果说某个元素不存在时,该元素一定不存在,如果该元素存在时,该元素可
能存在,因为有些哈希函数存在一定的误判。
布隆过滤器删除
布隆过滤器不能直接支持删除工作,因为在删除一个元素时,可能会影响其他元素。
比如:删除上图中 "tencent" 元素,如果直接将该元素所对应的二进制比特位置 0 “baidu” 元素也
被删除了,因为这两个元素在多个哈希函数计算出的比特位上刚好有重叠。
一种支持删除的方法:将布隆过滤器中的每个比特位扩展成一个小的计数器,插入元素时给 k 个计
数器 (k 个哈希函数计算出的哈希地址 ) 加一,删除元素时,给 k 个计数器减一,通过多占用几倍存储
空间的代价来增加删除操作。
缺陷:
1. 无法确认元素是否真正在布隆过滤器中
2. 存在计数回绕
布隆过滤器优点
1. 增加和查询元素的时间复杂度为 :O(K), (K 为哈希函数的个数,一般比较小 ) ,与数据量大小无关
2. 哈希函数相互之间没有关系,方便硬件并行运算
3. 布隆过滤器不需要存储元素本身,在某些对保密要求比较严格的场合有很大优势
4. 在能够承受一定的误判时,布隆过滤器比其他数据结构有这很大的空间优势
5. 数据量很大时,布隆过滤器可以表示全集,其他数据结构不能
6. 使用同一组散列函数的布隆过滤器可以进行交、并、差运算
布隆过滤器缺陷
1. 有误判率,即存在假阳性 (False Position) ,即不能准确判断元素是否在集合中 ( 补救方法:再
建立一个白名单,存储可能会误判的数据 )
2. 不能获取元素本身
3. 一般情况下不能从布隆过滤器中删除元素
4. 如果采用计数方式删除,可能会存在计数回绕问题

到了这里,关于【C++】海量数据处理面试题(位图和布隆过滤器)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构:位图、布隆过滤器以及海量数据面试题

    1.1概念 引入 给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中。 (1)遍历: 时间复杂度O(N) (2)排序加二分:时间复杂度O(N*logN) 其中 方法(2)是行不通 的,因为内存很难装下这么多数据(40亿整数大概为16G)。 方法(1) 可行

    2024年02月05日
    浏览(44)
  • 哈希的应用 -- 布隆过滤器与海量数据处理

    布隆过滤器是由布隆(Burton Howard Bloom)在1970年提出的 一种紧凑型的、比较巧妙的概率型数据结构,特点是高效地插入和查询,以用来告诉你 “ 某样东西一定不存在或者可能存在 ”,它是用多个哈希函数,将一个数据映射到位图结构中。此种方式不仅可以提升查询效率,也

    2024年02月02日
    浏览(44)
  • 【C++】位图与布隆过滤器(内含相关高频面试题)

      本篇文章会对 位图和布隆过滤器进行详解 。同时还会给出 位图和布隆过滤器相关的高频面试题与解答 。希望本篇文章会对你有所帮助。  文章目录 一、位图的引入  1、1 查找整数(腾讯面试题) 1、2 解决方法1 1、3 解决方法2   1、3、1 外部排序 二、位图的原理与实现

    2024年02月12日
    浏览(40)
  • 【数据结构】盘点那些经典的 [哈希面试题]【哈希切割】【位图应用】【布隆过滤器】(10)

    前言 大家好吖,欢迎来到 YY 滴 数据结构 系列 ,热烈欢迎! 本章主要内容面向接触过C++的老铁 主要内容含: 欢迎订阅 YY 滴C++专栏!更多干货持续更新!以下是传送门! YY的《C++》专栏 YY的《C++11》专栏 YY的《Linux》专栏 YY的《数据结构》专栏 YY的《C语言基础》专栏 YY的《

    2024年02月04日
    浏览(58)
  • 【C++练级之路】【Lv.20】位图和布隆过滤器(揭开大数据背后的神秘面纱)

    快乐的流畅:个人主页 个人专栏:《算法神殿》《数据结构世界》《进击的C++》 远方有一堆篝火,在为久候之人燃烧! 哈希映射 的思想,在实际中有许多运用,之前介绍的 哈希表 是一种经典的应用场景,而今天我们将了解其他的哈希数据结构—— 位图和布隆过滤器 ,它

    2024年04月12日
    浏览(50)
  • 【C++】位图应用 | 布隆过滤器

    给40亿个不重复的无符号整数,没排过序,给一个无符号整数,如何快速判断一个数是否在这40亿个数中 正常思路: 1.排序 + 二分查找 2.放入 哈希表 或者 红黑树 10亿字节 约等于 1GB 40亿个整数约等于 16GB 如果使用上述的两种方法, 内存不够 哈希 的 直接定址法 的 哈希映射

    2024年02月08日
    浏览(44)
  • 【C++】哈希(位图,布隆过滤器)

    今天的内容是哈希的应用:位图和布隆过滤器 目录 一、位图 1.位图概念 2.位图的应用 二、哈希切分 三、布隆过滤器 1.布隆过滤器的概念 2.布隆过滤器的应用 四、总结   今天的内容从一道面试题开始引入: 给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何

    2024年02月01日
    浏览(37)
  • C++哈希应用——位图布隆过滤器

    用哈希表存储用户记录,缺点是需要消耗较大的内存;用位图存储用户记录,缺点是位图一般处理整形,内容是字符串或者自定义类型就很勉强。基于以上,若将哈希和位图结合,称为布隆过滤器,会不会把上面的问题都解决了呢? 概念 布隆过滤器是一种概率型数据结构。

    2024年02月04日
    浏览(53)
  • 【C++】哈希位图和布隆过滤器

    哈希位图和布隆过滤器都是常用的概率数据结构,用于高效地判断一个元素是否存在于一个集合当中,但它们在实现方法和各自的优缺点上有所区别。 哈希位图 哈希位图(Hash Bitmap)是由一个位数组构成,每个元素(通常是一个整数)被映射到位数组中的某个位置。对于集合

    2024年02月08日
    浏览(49)
  • [C++]哈希应用之位图&布隆过滤器

               主厨:邪王真眼 主厨的主页:Chef‘s blog   所属专栏:c++大冒险        我们之前学习了哈希表,哈希表通过映射关系,实现了O(1)的复杂度来查找数据,哈希在实践中是一个非常重要的思想,今天要学习的就是哈希思想的两大应用:位图与布隆过滤器 给 40 亿个

    2024年04月15日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包