位图(布隆过滤器)

news2024/11/15 12:12:06

 bitset/bitmap

给40亿个不重复的无符号整数,没排过序。给1个无符号整数,如何快速判断一个数是否在这40亿个数中。

 

​
#pragma once

#include <vector>
#include <string>
#include <time.h>

template<size_t N>
class bitset
{
public:
	bitset()
	{
		_bits.resize(N/8 + 1, 0);
	}     

	void set(size_t x)
	{
		size_t i = x / 8;
		size_t j = x % 8;

		_bits[i] |= (1 << j);//将对应的比特位设置成为1
	}

	void reset(size_t x)
	{
		size_t i = x / 8;//计算x映射的位在第i个char数组位置
		size_t j = x % 8;//计算x映射的位在这个char的第j个比特位

		_bits[i] &= ~(1 << j);//和0与是0,和1与不变。
	}

	bool test(size_t x)//查看x在不在
	{
		size_t i = x / 8;
		size_t j = x % 8;

		return _bits[i] & (1 << j);
	}

private:
	vector<char> _bits;
};

void test_bitset1()
{
	bitset<100> bs;
	bs.set(10);
	bs.set(11);
	bs.set(15);
	cout << bs.test(10) << endl;
	cout << bs.test(15) << endl;

	bs.reset(10);

	cout << bs.test(10) << endl;
	cout << bs.test(15) << endl;

	bs.reset(10);
	bs.reset(15);

	cout << bs.test(10) << endl;
	cout << bs.test(15) << endl;
}

void test_bitset2()
{
	//bitset<-1> bs1;//传-1可以开最大的空间42亿多
	bitset<0xFFFFFFFF> bs1;//这样写也可以开最大的空间42亿多
}

 twobitset

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

//用两个bitset封装
template<size_t N>
class twobitset
{
public:
	void set(size_t x)
	{
		// 00 -> 01
		if (_bs1.test(x) == false
		&& _bs2.test(x) == false)
		{
			_bs2.set(x);
		}
		else if (_bs1.test(x) == false
			&& _bs2.test(x) == true)
		{
		// 01 -> 10
			_bs1.set(x);
			_bs2.reset(x);
		}
		// 10代表至少出现两次,就不变化了。
	}

	void Print()//打印只出现一次的整数
	{
		for (size_t i = 0; i < N; ++i)
		{
			if (_bs2.test(i))
			{
				cout << i << endl;
			}
		}
	}

public:
	bitset<N> _bs1;
	bitset<N> _bs2;
};

void test_twobitset()
{
	int a[] = { 3, 45, 53, 32, 32, 43, 3, 2, 5, 2, 32, 55, 5, 53,43,9,8,7,8 };
	twobitset<100> bs;
	for (auto e : a)
	{
		bs.set(e);
	}

	bs.Print();
}

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

方法1:其中一个文件的值,读到内存的一个位图中再读取另一个文件,判断在不在上面位图中,在就是交集!存在问题:找出来的交集存在重复的值。

 方法2:

遍历,if(bs1.test(i)&&bs2.test(i))就是交集。

2.1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数。和twobitset问题类似,00(出现0次)->01(出现1次)->10(出现2次)->11(出现3次)

位图的优点就是速度快、节省空间;缺点是只能映射整形,其他类型如:浮点数、string等等不能存储映射。

布隆过滤器

布隆过滤器减少磁盘IO或者网络请求,因为一旦一个值必定不存在的话,我们可以不用进行后续昂贵的查询请求。布隆过滤器正常情况下是不支持reset的。

struct BKDRHash//仿函数,将一个字符串转成整型。
{
	size_t operator()(const string& s)
	{
		size_t hash = 0;
		for (auto ch : s)
		{
			hash += ch;
			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;
	}
};

// N最多会插入key数据的个数
template<size_t N,
class K = string,
class Hash1 = BKDRHash,
class Hash2 = APHash,
class Hash3 = DJBHash>//Hash是将K转换成为整型,这里是一个key映射到三个位置。
class BloomFilter
{
public:
	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);

		//cout << hash1 << " " << hash2 << " " << hash3 << " " << endl << endl;
	 }

	bool test(const K& key)//需要三个位置在才能证明这个key值存在
	{
		size_t len = N*_X;

		size_t hash1 = Hash1()(key) % len;
		if (!_bs.test(hash1))
		{
			return false;
		}

		size_t hash2 = Hash2()(key) % len;
		if (!_bs.test(hash2))
		{
			return false;
		}

		size_t hash3 = Hash3()(key) % len;
		if (!_bs.test(hash3))
		{
			return false;
		}

		// 在      不准确的,存在误判
		// 不在    准确的

		return true;
	}
private:
	static const size_t _X = 6;
	bitset<N*_X> _bs;
};

void test_bloomfilter1()
{
	BloomFilter<100> bs;
	bs.set("sort");
	bs.set("bloom");
	bs.set("hello world hello bit");
	bs.set("test");
	bs.set("etst");
	bs.set("estt");

	cout << bs.test("sort") << endl;
	cout << bs.test("bloom") << endl;
	cout << bs.test("hello world hello bit") << endl;
	cout << bs.test("etst") << endl;
	cout << bs.test("test") << endl;
	cout << bs.test("estt") << endl;

	cout << bs.test("ssort") << endl;
	cout << bs.test("tors") << endl;
	cout << bs.test("ttes") << endl;
}


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;
}

​

 布隆过滤器使用场景是什么?
1、能容忍误判的场景。比如:注册时,快速判断昵称是否使用过。因为昵称在布隆过滤器判断的结果是没有用过就一定是没有用过,布隆过滤器判断结果是用过了则实际上有一定的概率并没有被用过。

2、给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?分别给出精确算法和近似算法。

 造成上述问题的原因:1、单个文件中,有大量不同的query;2、单个文件中,有某个大量重复的query;

3. 给一个超过100G大小的log file, log中存着IP地址,设计算法找到出现次数最多的IP地址?
如何找到top K的IP?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2097573.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实战docker第一天——windows安装docker,测试,并解决被墙办法

Docker 是一个开源的容器化平台&#xff0c;它允许开发者将应用程序及其所有依赖项打包在一个名为“容器”的单独环境中&#xff0c;从而确保应用程序在任何环境下都能一致地运行。以下是 Docker 的一些核心概念及其意义&#xff1a; 容器化&#xff1a;Docker 通过将应用程序及…

外卖霸王餐系统的运作流程及注意事项

霸王餐系统概述 一、系统组成 商家端发布霸王餐活动信息&#xff0c;包括菜品、时间、人数等。管理活动报名者信息。查看活动效果和用户反馈。用户端浏览和报名感兴趣的霸王餐活动。提交评价和反馈。管理后台审核商家和用户信息。监控活动流程和数据。 二、运作流程 1.商家…

去中心化网络:Web3如何颠覆传统互联网

在互联网的演进过程中&#xff0c;从最初的静态网页到交互式的Web2.0&#xff0c;技术的进步不断推动着网络的变革。而如今&#xff0c;Web3作为互联网的下一代技术&#xff0c;正以其去中心化的特性&#xff0c;逐步颠覆传统的互联网架构。本文将深入探讨Web3如何通过去中心化…

CH9114 USB转四串口替换FT4232H系列芯片

之前针对CH9101系列芯片替换FT232系列芯片型号发布了一系列文章&#xff0c;想必有需要的同学或工程师已经体验过替换的便捷之处了。早前CH系列芯片只发现有单串口型号的替换&#xff0c;4串口芯片苦于迟迟找不到替换型号&#xff0c;所幸今年和他们工程师聊天中获悉&#xff0…

【C语言必学知识点六】自定义类型——结构体

结构体 导读一、自定义类型二、结构体2.1 什么是结构体2.2 结构的声明2.2.1 构体的声明格式2.2.2 结构体的特殊声明 2.3 关键字typedef2.3.1 typedef的作用2.3.2 typedef的使用2.3.2 typedef在结构体中的应用 2.4 结构体变量的创建和初始化2.4.1 结构体变量创建的区别2.4.2 重命…

系统一执行systemctl就报错`No space left on device`,全部拿下

前言 在现代计算机系统中&#xff0c;存储空间似乎总是无尽的&#xff0c;但当你突然看到“No space left on device”的错误消息时&#xff0c;那种突然的焦虑感可不是开玩笑的。这就像是你在一个精心设计的房间里忽然发现最后一块空地也被填满了——这时候你会发现&#xff…

12kg级折叠翼巡飞无人飞行器技术详解

12kg级折叠翼巡飞无人飞行器&#xff08;以下简称“飞行器”&#xff09;是一种集高机动性、长续航、易于部署于一体的先进无人机系统。该飞行器设计巧妙&#xff0c;能够在复杂环境中灵活飞行&#xff0c;执行侦察、监测、目标跟踪、通信中继等多种任务。其独特的折叠翼设计大…

电路基础 ---- 电压源、电流源、受控电源

1 电压源 定义&#xff1a;两端电压总是保持定值&#xff0c;与流过它的电流无关 1.1 分析 对于如下电路&#xff1a; 当 R → 0 R\to 0 R→0&#xff08;短路&#xff09;时&#xff0c; i ∞ i\infty i∞&#xff08;会烧坏电压源&#xff09;当 R → ∞ R\to\infty R…

EPLAN中部件库的导入和使用方法

EPLAN中部件库的导入和使用方法 如下图所示,点击工具-----部件------管理, 在弹出的窗口中点击附加------导入, 找到自己需要导入的文件,后缀名为EDZ,点击打开, 如下图所示,勾选"更新已有数据集并添加新建数据集",点击确定, 如下图所示,正在导

光影漫游者:科技感十足的圆形气膜场馆—轻空间

在现代品牌发布会和大型活动中&#xff0c;场馆的选择往往直接影响活动的整体效果。随着科技的不断进步和品牌对创新展示空间的需求增加&#xff0c;越来越多的企业开始寻求兼具科技感和视觉冲击力的场地。光影漫游者&#xff0c;以其独特的圆形气膜外形和先进的科技感设计&…

基于Django的MySQL项目建设计划

构建一个基于 Django 和 MySQL 的项目需要经过多个阶段的规划和实施。以下是一个详细的建设计划&#xff0c;分为项目准备、开发、测试和部署等几个关键阶段。 1、问题背景 为了完成大学的 “问答网站” 项目&#xff0c;需要在几天内完成项目的计划&#xff0c;并于下周二准备…

Qt QGraphicsView实现图片放缩、鼠标拖动移动、鼠标点位置放大缩小_图片查看

QtQGraphicsView实现图片放缩、鼠标拖动移动、鼠标点位置放大缩小 头文件&#xff1a; #ifndef TIMGWIDGET_H #define TIMGWIDGET_H#include <QGraphicsItem> #include <QMainWindow> #include <QObject> #include <QWidget>// class TImgWidget : pu…

快准齐的机器视觉:用上了就知道,检测还能怎么玩

随着工业4.0的到来 &#xff0c;工厂追求自动化&#xff0c;智能化的发展需求越来越高&#xff0c;机器视觉技术的发展也越来越受到人们关注。机器视觉能做什么&#xff0c;能做到什么程度很多人都只是有一定的了解&#xff0c;今天就这案例给大家看看。 这是一个端子生产委托…

基于Java实现(MVC)图书管理系统

需求分析 系统用户分为&#xff1a;借阅者&#xff08;包括学生、教师及其他用户&#xff09;、管理员 借阅者的主要功能&#xff1a; 个人信息管理&#xff1a;查看、修改个人基本信息&#xff1b;查询图书、借书、还书、查询借阅记录、本人可借图书总数、目前在借的数量等&…

基于jetpackCompose实现最简单的悬浮窗效果

最近在研究使用compose框架实现悬浮窗效果&#xff0c;期间遇到很多问题&#xff0c;各种搜索结果琳琅满目&#xff0c;不是插件就是非常复杂的代码&#xff0c;只能潜心研究&#xff0c;最后得出了这个几行代码就能实现悬浮窗的方案。 为了技术人的脑力能得到应有的回报&#…

PTA - C语言接口题集

目录 6-1 计算两个复数之积&#xff08;结构体函数&#xff09;6-2 字符定位&#xff08;返回字符的地址&#xff0c;指针&#xff09;6-3 求结构体平均成绩&#xff08;变量名(数组名)用.;指针(带有*)用->&#xff09;6-4 删除字符串中数字字符6-5 使用函数找出数组中的最大…

系统更新报“更新失败“

系统更新报"更新失败" 本章只针对统信UOS系统 系统检查更新失败&#xff0c;或者系统更新的过程中失败&#xff0c;或者提示依赖错误&#xff0c;检测更新失败。 故障处理&#xff1a; 检查下网络是否正常&#xff0c;系统时间是否正常&#xff1b;开启开发者&…

MOS管驱动电路阻值如何选取?以及为什么要有下拉电阻

开通时&#xff0c;电源为高电平&#xff0c;会通过Rg1给MOS的Cgs充电&#xff0c;关断时&#xff0c;Cgs通过Rg2放电.实现慢开快关的过程 如果驱动阻值太大&#xff0c;开关会很慢&#xff0c;会让MOS管的损耗增加&#xff0c;降低了效率&#xff0c;dv/dt&#xff0c;di/dt也…

电路基础 ---- 运放里的虚短虚断

令人稀里糊涂的虚短虚断 想必好多人在学习硬件电路分析时&#xff0c;都会听到虚短虚断这个专业术语&#xff0c;但是对于新手玩家&#xff0c;这个术语不好理解&#xff0c;比如我自己&#xff0c;经常将这两个概念混淆。最近刷到大佬的视频&#xff0c;讲解的非常简洁易懂&a…

蓝卓与用友、中控签署全面战略合作协议

8月9日&#xff0c;蓝卓数字科技有限公司&#xff08;以下简称“蓝卓”&#xff09;与用友网络科技股份有限公司&#xff08;以下简称“用友网络”&#xff09;与中控技术股份有限公司&#xff08;以下简称“中控技术”&#xff09;签署全面战略合作协议。三方将在平台产品融合…