布隆过滤器

2023-12-17

布隆过滤器地提出:

我们在使用新闻客户端看新闻时,它会给我们不停地推荐新的内容,它每次推荐时要去重,去掉
那些已经看过的内容。问题来了,新闻客户端推荐系统如何实现推送去重的? 用服务器记录了用
户看过的所有历史记录,当推荐系统推荐新闻时会从每个用户的历史记录里进行筛选,过滤掉那
些已经存在的记录。 如何快速查找呢?
1. 用 哈希表存储用户记录 ,缺点: 浪费空间
2. 用位图存储用户记录,缺点: 位图一般只能处理整形 如果内容编号是字符串,就无法处理

3. 将 哈希与位图结合 ,即 布隆过滤器

布隆过滤器的概念:

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

位图的实现(布隆过滤器是基于位图的基础上实现的):

template<size_t bitCount>
class Bitset
{
public:
	Bitset(size_t bitCount=10)
		:_bitCount(bitCount)
		, _bit((bitCount >> 5) + 1,0)
	{

	}
	//设置which比特位为1
	void set(size_t which)
	{
		if (which > _bitCount)
		{
			return;
		}
		size_t index = which / 32;
		size_t pos = which % 32;

		_bit[index] |= (1 << pos);//"|"有一则是一 
	}
	//检测which比特位为1
	bool test(size_t which)
	{
		if (which > _bitCount)
		{
			return false;
		}
		size_t index = which / 32;
		size_t pos = which % 32;
		return _bit[index] & (1 << pos);//有0则为0 并没有改变原有的数据
	}
	//将which比特位设置为0
	void reset(size_t which)
	{
		if (which > _bitCount)
		{
			return;
		}
		size_t index = which / 32;
		size_t pos = which % 32;
		
		_bit[index] &= ~(1 << pos);
	}
	//获取位图中的比特位总数
	size_t size()const
	{
		return _bitCount;
	}


private:
	vector<int> _bit;
	size_t _bitCount;
};

布隆过滤器的实现:

//哈希函数 将原始数据通过哈希函数的转换形成特定的整形进行存储
struct BKDRHash
{
	size_t operator()(const string& s)
	{
		// BKDR
		size_t value = 0;
		for (auto ch : s)
		{
			value *= 31;
			value += ch;
		}
		return value;
	}
};
struct APHash
{
	size_t operator()(const string& s)
	{
		size_t hash = 0;
		for (long i = 0; i < s.size(); i++)
		{
			if ((i & 1) == 0)
			{
				hash ^= ((hash << 7) ^ s[i] ^ (hash >> 3));
			}
			else
			{
				hash ^= (~((hash << 11) ^ s[i] ^ (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:
	//BloomFilter(){}
	void set(const K& key)
	{
		size_t len = N;
		size_t x1 = Hash1()(key) % len;
		size_t x2 = Hash2()(key) % len;
		size_t x3 = Hash3()(key) % len;
		_bs.set(x1);
		_bs.set(x2);
		_bs.set(x3);
	}
	//检查存不存在
	bool Test(const K& key)
	{
		size_t len = N;
		size_t x1 = Hash1()(key) % len;
		if (_bs.test(x1)==false)
			return false;
		size_t x2 = Hash2()(key) % len;
		if (_bs.test(x2) == false)
			return false;
		size_t x3 = Hash3()(key) % len;
		if (_bs.test(x3) == false)
			return false;

		return true;//存在误判 布隆过滤器的特点 不存在是肯定的
	}
	//不支持删除 可能会影响其他值
	//void Reset(const K& key);
private:
	Bitset<N> _bs;
};

布隆过滤器的测试:

void TestBF1()
{
	BloomFilter<100> bf;
	bf.set("猪八戒");
	bf.set("沙悟净");
	bf.set("孙悟空");
	bf.set("二郎神");

	cout << bf.Test("猪八戒") << endl;
	cout << bf.Test("沙悟净") << endl;
	cout << bf.Test("孙悟空") << endl;
	cout << bf.Test("二郎神") << endl;
	cout << bf.Test("二郎神1") << endl;
	cout << bf.Test("二郎神2") << endl;
	cout << bf.Test("二郎神 ") << endl;
	cout << bf.Test("太白晶星") << endl;
}
void TestBF2()
{
	srand(time(0));
	const size_t N = 100000;
	BloomFilter<N * 10> bf;

	std::vector<std::string> v1;
	//std::string url = "https://www.cnblogs.com/-clq/archive/2012/05/31/2528153.html";
	std::string url = "猪八戒";

	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 urlstr = url;
		urlstr += std::to_string(9999999 + i);
		v2.push_back(urlstr);
	}

	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 = "孙悟空";
		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;
}

布隆过滤器的优点:

1. 增加和查询元素的时间复杂度为:O(K), (K为哈希函数的个数,一般比较小),与数据量大小无

2. 哈希函数相互之间没有关系,方便硬件并行运算
3. 布隆过滤器不需要存储元素本身,在某些对保密要求比较严格的场合有很大优势
4. 在能够承受一定的误判时,布隆过滤器比其他数据结构有这很大的空间优势
5. 数据量很大时,布隆过滤器可以表示全集,其他数据结构不能
6. 使用同一组散列函数的布隆过滤器可以进行交、并、差运算

布隆过滤器的缺陷:

1. 有误判率,即存在假阳性(False Position),即不能准确判断元素是否在集合中(补救方法:再
建立一个白名单,存储可能会误判的数据)
2. 不能获取元素本身
3. 一般情况下不能从布隆过滤器中删除元素
4. 如果采用计数方式删除,可能会存在计数回绕问题

布隆过滤器的应用:

1. 给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?分别给出
精确算法和近似算法
2. 如何扩展BloomFilter使得它支持删除元素的操作

哈希切割:

给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址?
与上题条件相同,如何找到top K的IP?如何直接用Linux系统命令实现?

位图的应用:

1. 给定100亿个整数,设计算法找到只出现一次的整数?
2. 给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集?
3. 位图应用变形:1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

布隆过滤器 的相关文章

  • ERP、SAP、MES 三者之间的区别是什么?

    ERP SAP MES之间有什么区别 SAP 思爱普 是ERP系统与企业管理解决方案 提供商 而ERP和MES是两个用途不一样的 管理系统 也就是说 SAP是一家厂商 提供包含ERP在内的管理系统 SAP搞清楚了 那么 ERP和MES 呢
  • GoLong的学习之路,进阶,Viper(yaml等配置文件的管理)

    本来有今天是继续接着上一章写微服务的 但是这几天有朋友说 再写Web框架的时候 遇到一个问题 就是很多的中间件 redis 微信 mysql mq 的配置信息写的太杂了 很不好管理 希望我能写一篇有管理配置文件的 所以这篇就放到今天写吧 微

随机推荐

  • 【抄作业】ImportError :cannot import name xxxxxx ,原博主Activewaste

    前情介绍 网上关于这种问题的解决方案一大堆 但是绝大多数都是不适用 或者说解决不了问题 我根据别人所遇到的和我自己遇到的 对这个问题整理了一下 希望能解决这个问题 问题分析 一 缺少这个module或者func或者package 缺少pyt
  • 波奇学Linux:环境变量,本地变量和内建命令

    Windows下的环境变量 echo PATH 查看指令搜索命令路径 在bash命令行输入的指令 系统根据PATH中的路径查询 增加PATH指令 PATH等于上面的路径 表示不同路径分割符 home boki lesson13代表新的路径
  • 基于java中SSM框架实现门诊药品管理系统演示【附项目源码+论文说明】

    基于java中SSM框架实现门诊药品管理系统演示 摘要 21世纪的今天 随着社会的不断发展与进步 人们对于信息科学化的认识 已由低层次向高层次发展 由原来的感性认识向理性认识提高 管理工作的重要性已逐渐被人们所认识 科学化的管理 使信息存储
  • 数说CS | 不招学硕?拟录取人数持续增长?北大软件与微电子学院为何如此热门?

    写在前面 北京大学软件与微电子学院 软件工程学科评估为A类 招收哪些专业 保研录取情况如何 今天 岛主就带你 深度揭秘北京大学软件与微电子学院 01 院校介绍 北京大学软件与微电子学院成立于2002年3月 如今已形成了一个学院 北京大学软件
  • 数说CS | 拟录取名额上涨,开设九推?上岸复旦大学计算机科学与技术学院更轻松了吗?

    写在前面 复旦大学计算机科学技术学院 学科评估为A类 招收哪些专业 保研录取情况如何 今天 岛主就带你 深度揭秘复旦大学计算机科学技术学院 01 院校介绍 复旦大学计算机学科创建于 中国计算机事业的起步期 始于 1956 年自主建造的国内第
  • 工业级路由器在货运物流仓储管理中的应用

    工业级路由器在货运物流仓储管理中扮演着重要的角色 为整个物流系统提供了稳定可靠的网络连接和数据传输支持 下面将从以下几个方面介绍工业级路由器在货运物流仓储管理中的应用 实时监控和追踪 工业级路由器通过与各种传感器 监控设备和物联网设备的连接
  • 人工智能自然语言处理:语言之美,算法之智

    导言 自然语言处理 Natural Language Processing NLP 是人工智能领域中备受关注的分支 致力于让计算机能够理解 处理和生成人类语言 本文将深入研究人工智能在自然语言处理领域的关键技术 应用场景以及未来发展趋势 1
  • 学长休学一年强势回归,截胡了我的保研名额……

    写在前面 保研是一场持久的战役 从评定保研资格到申请梦校offer 每一步都需要保研er费尽九牛二虎之力 其中 最怕的便是半路杀出个程咬金 让一切的努力化为乌有 算到了加分刺客 算到了名额变动 独独没想到 被上届休学归来的学长姐挤占了保研名
  • 人工智能计算机视觉:解析现状与未来趋势

    导言 随着人工智能的迅速发展 计算机视觉技术逐渐成为引领创新的关键领域 本文将深入探讨人工智能在计算机视觉方面的最新进展 关键挑战以及未来可能的趋势 1 简介 计算机视觉是人工智能的一个重要分支 其目标是使机器具备类似于人类视觉的能力 这一
  • C++函数模板与类模板

    目录 C 模板定义 函数模板 类模板 类模板的定义 模板的优缺点 模板的优点 模板的缺点 C 模板定义 C 模板允许程序员在通用编程中创建可重用的代码 这种编程技术基于模板的编
  • echarts环形饼图

    效果示例 代码汇总 pieCharts let data const providerResult name 智诺 value 23 name 海康 value 5 name 大华 value 5 name 云科 value 23 name
  • 开考在即?四六级押题卷免费送!

    距12月16日四六级考试 还有 1个多月 的时间啦 在这短短一月时间里 只有 考前押题和历年真题 才能在短时间内帮助到你们 所以 岛主给你们准备了 今年 12月四六级绝密押题卷 还包含 历年真题卷 答案详解 没有时间复习 想考前突击一下的同
  • 在openEuler上安装openGauss2023年12月最新openGauss5.0.0LTS版本全图片解析

    先说环境 虚拟机 openEuler22 03 LTS ip 192 168 88 129 普通用户 yirc99 和 root用户 主机win10 要安装的数据库 openGauss 5 0 0 LTS 在下面的文章中可能会出现命令不存在
  • 迅为IMX6UL核心板在便携式医疗设备中的应用方案

    在科技日益发展的今天 便携式医疗设备变得越来越受欢迎 这些小巧 轻便的设备 例如IMX6UL核心板 为医疗行业带来了巨大的变革 它们不仅便于携带 而且集成了多种功能 满足了人们对健康管理的各种需求 便携式医疗设备在当今社会越来越受到欢迎 这
  • 两路wav文件读取解析和混音输出并使用WaveOut相关API播放

    目录 wav文件格式简介 wav文件头定义 读取wav文件 读取背景音文件 音频混音 使用Windows WaveOut 相关API播放混音后的音频数据 将混音后的数据保存到新的wav文件中
  • 数字化和数智化一字之差,究竟有何异同点?

    在2023杭州云栖大会的一展台内 桌子上放着一颗番茄和一个蛋糕 一旁的机器人手臂融入 通义千问 大模型技术后 变得会 思考 不仅能描述 看 到了什么 还能确认抓取的是番茄而不是蛋糕 传统的机械臂通常都只能基于预设的指令和流程来执行任务 引入
  • FMOD Core API 指南

    目录 3 Core API 指南 3 1 什么是 Core API 3 2 链接的插件 3 2 1 静态 3 2 2 动态 3 3 API 功能
  • gdi32.dll文件缺失导致程序无法运行问题

    其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题 如果是新手第一时间会认为是软件或游戏出错了 其实并不是这样 其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库 这时你可以下载这个gdi32 d
  • 计算机毕业设计:基于python二手商品交易网站 二手商品交易系统(附源码)✅

    博主介绍 全网粉丝10W 前互联网大厂软件研发 集结硕博英豪成立工作室 专注于计算机相关专业 毕业设计 项目实战6年之久 感兴趣的可以先收藏起来 点赞 关注不迷路 毕业设计 2023 2024年计算机专业毕业设计选题汇总 建议收藏 毕业设计
  • 布隆过滤器

    布隆过滤器地提出 我们在使用新闻客户端看新闻时 它会给我们不停地推荐新的内容 它每次推荐时要去重 去掉 那些已经看过的内容 问题来了 新闻客户端推荐系统如何实现推送去重的 用服务器记录了用 户看过的所有历史记录 当推荐系统推荐新闻时会从每个