【数据结构】哈希应用——位图、布隆过滤器

文章目录

  • 一、位图
    • 1.基本概念
    • 2.基本实现
    • 3.基本应用
      • 3.1 找100亿个整数只出现一次的数
      • 3.2 两个文件分别有100亿整数,1G内存,求交集
  • 二、布隆过滤器
    • 1、基本实现
    • 2、基本应用
      • 2.1过滤一部分的数据
      • 2.2 两个文件,分别100亿个查询,1G内存,精确求文件交集
      • 2.3给一个超过100G大小的文件 其中存着IP地址, 找到出现次数最多的IP地址
  • 总结

一、位图

1.基本概念

 假如要给你几万个整形数据判断在不在,想必你一定会用哈希,但是如果给你40亿个整形数据,限制运行内存为16GB,然后再判断在不在,不知阁下当如何应对?

 首先,我们先来分析一下问题,40亿个整形数据,为160亿个字节,又因为10亿个字节,大概为1GB,由此可换算为16GB,到这你可会觉得刚好,好继续分析如果采用哈希或者红黑树,哈希表要开的数据一定比16GB还要大,如果红黑树还有指针的信息,也比16GB要大,那么有没有什么方法呢?

  • 分析在不在只需用1个比特位即可表示。

2.基本实现

#include<vector>
using namespace std;
namespace MY_STL
{template<size_t N>class bitset{public:bitset(){//N——数据,换算成比特int size = N / 32 + 1;//向上取整_bit.resize(size,0);}void set(size_t n){//求出所在第pos个整形位置int pos = n / 32;//求出在第pos位置的num位数.int num = n % 32;//对pos位置的num位变1(或操作)_bit[pos] |= (1 << num);}void reset(size_t n){//求出所在第pos个整形位置int pos = n / 32;//求出在第pos位置的num位数.int num = n % 32;//将pos个整形的num位变0,其它位置不变。_bit[pos] &= ~(1 << num);}bool test(size_t n){//求出所在第pos个整形位置int pos = n / 32;//求出在第pos位置的num位数.int num = n % 32;return _bit[pos] & (1 << num);//只要指定是0,就为假,非0为真。}private:vector<int> _bit;};
}

3.基本应用

3.1 找100亿个整数只出现一次的数

  • 思路:两个位图,组合起来,01表示只出现一次,00表示出现两次,10表示出现两次及以上。

基本实现:

	template<size_t N>class TwoBitSet{public:void set(size_t n){//01表示出现一次if (!_bit1.test(n) && _bit2.test(n)){//改成10_bit1.set(n), _bit2.reset(n);}//00表示出现0次else if (!_bit1.test(n) && !_bit2.test(n)){_bit2.set(n);}//出现两次以上不用改。}bool is_once(size_t n){//01表示出现一次。return !_bit1.test(n) && _bit2.test(n);}private:bitset<N> _bit1;bitset<N> _bit2;};

测试代码:

void TwoBitSet()
{MY_STL::TwoBitSet<-1> twobits;//-1表示无符号的最大整数。int arr[] = { 1,1,2,2,3,4,5,7,5,7,8,0,8,0 };for (auto e : arr){twobits.set(e);}for (auto e : arr){if (twobits.is_once(e)){cout << e << " ";}}
}

3.2 两个文件分别有100亿整数,1G内存,求交集

  • 思路:两个数求交集,要先在bitset里面去重,然后一个一个数据进行比对,如果两个数都存在,则是交集的数字。

测试代码:

void BitTest1()
{MY_STL::bitset<300> bit1;MY_STL::bitset<300> bit2;int arr1[] = { 1,1,2,3,4,5,7,8,9,10 };int arr2[] = { 4,5,7,11,23,45,23,254,231 };for (auto e : arr1){bit1.set(e);}for (auto e : arr2){bit2.set(e);}vector<int> same;for (size_t i = 0; i < 251; i++){if (bit1.test(i) && bit2.test(i)){same.push_back(i);}}for (auto e : same){cout << e << " ";}
}

二、布隆过滤器

 当转换为字符串时,进行哈希处理,难免就会产生冲突,通过之前的学习,我们可以从中了解到,冲突是无法避免的,只能尽可能的减少,布隆过滤器就是用来处理海量数据(一般情况下为字符串),减少冲突的。

 如何尽可能的减少冲突呢?

 源自于一个布隆的人,最开始想要避免冲突,最后发现是不可能实现的,转而想到如何尽可能的减少冲突,最后想到了既然冲突是由一个哈希函数产生的,那我多用几个哈希函数,同时处理,然后进行查找,如果有一个不在的话,这就说明不存在,这个结果是一定准确的,如果都在的话,说明存在,但结果不一定准确。

既然是多弄几种哈希函数这不简单,找几个现成的字符串哈希我们实现一波。

字符串哈希冲突算法

1、基本实现

namespace MY_STL
{struct BKDRHash{size_t operator()(const string& str){size_t hash = 0;for (auto ch : str){hash = hash * 131 + ch;}return hash;}};struct APHash{size_t operator()(const string& str){register size_t hash = 0;size_t ch;for (long i = 0; i < str.size(); i++){size_t ch = str[i];if ((i & 1) == 0){hash ^= ((hash << 7) ^ ch ^ (hash >> 3));}else{hash ^= (~((hash << 11) ^ ch ^ (hash >> 5)));}}return hash;}};struct SDBMHash{size_t operator()(const string& str){register size_t hash = 0;for (auto ch : str){hash = 65599 * hash + ch;}return hash;}};template<size_t N,class T,class Hash1 = BKDRHash,class Hash2 = APHash,class Hash3 = SDBMHash>class BloomFilter{public:void set(const T& data){size_t hash1 = Hash1()(data) % N;size_t hash2 = Hash2()(data) % N;size_t hash3 = Hash3()(data) % N;_bit.set(hash1);_bit.set(hash2);_bit.set(hash3);}bool test(const T& data){size_t hash1 = Hash1()(data) % N;size_t hash2 = Hash2()(data) % N;size_t hash3 = Hash3()(data) % N;if (!_bit.test(hash1) || !_bit.test(hash2) || !_bit.test(hash3))return false;return true;}private:bitset<N> _bit;};
}

说明:这里并没有写reset,也就是删除函数,原因很简单,因为一旦删除,那就会影响其它的值的查找

拓展:如何选择适合的哈希长度?

  • 这里给出一个由实验得出的公式。
    在这里插入图片描述
  • k 为哈希函数个数,m 为布隆过滤器长度,n 为插入的元素个数,ln2约等于0.963

2、基本应用

2.1过滤一部分的数据

 在数据库的查询中会比较慢,这时如果我们能用布隆过滤器查询,如果不在,则直接返回结果即可,如果在,再用数据库进行查询,这样效率会高不少,同时还能减少数据库的负载。

2.2 两个文件,分别100亿个查询,1G内存,精确求文件交集

 首先100亿个查询,可以在文件中分成1000个左右的小文件,进行编号,然后再把这100亿个查询通过内存进行哈希再分发到这1000个小文件中,再对另一个文件执行同样的操作,最后两个文件的数据依次进行求交集,但是这样会涉及一个问题,首先哈希冲突如果大量聚集,就会导致某一个文件很大,这就要讨论两个问题,哈希冲突可能是由相同的数据产生的,如何判断这种情况呢?其实用set进行判断,把这个文件读到set里面,如果set没有抛异常,说明是由大量相同数据产生的,可以直接读到内存中,如果set抛异常了,说明不是有相同数据产生的,此时我们还要再把这个文件再进行分,比如再分成20份,再换一个哈希函数,再进行读。

2.3给一个超过100G大小的文件 其中存着IP地址, 找到出现次数最多的IP地址

 利用上面一题的思路,对文件进行切分,然后依次对每一个小文件用map统计次数,保留最多的那一个,依次读取更新出现次数最多的Ip地址即可。

总结

 今天的分享到此就结束了,如果有所帮助点个赞鼓励一下吧!

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

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

相关文章

[Linux入门]---管理者操作系统

文章目录 1.操作系统概念2.设计操作系统的目的3.操作系统如何进行管理系统调用和库函数概念 1.操作系统概念 任何计算机系统都包含一个基本的程序集合&#xff0c;称为操作系统(OS)。笼统的理解&#xff0c;操作系统包括&#xff1a; 内核&#xff08;进程管理&#xff0c;内存…

C# OpenCvSharp Yolov8 Detect 目标检测

效果 项目 代码 using OpenCvSharp; using OpenCvSharp.Dnn; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms;namespace Open…

索引(含B树、B+树)

1、索引&#xff08;index&#xff09; 索引是在数据库表的字段上添加的&#xff0c;是为了提高查询效率存在的一种机制。 一张表的一个字段可以添加一个索引&#xff0c;当然&#xff0c;多个字段联合起来也可以添加索引。 索引相当于一本书的目录&#xff0c;是为了缩小扫描…

Avl树(有详细图解)

目录 介绍 引入 概念 特点 模拟实现 思路 插入 旋转 左旋 无子树 有子树 右旋 无子树 有子树 左右旋 引入(也就是有子树版本的抽象图解) 解决方法(也就是左右旋) 总结 无子树(也就是curright的位置就是newnode) 有子树 模型高度解释 旋转 更新三个…

深度学习修炼(二)全连接神经网络 | Softmax,交叉熵损失函数 优化AdaGrad,RMSProp等 对抗过拟合 全攻略

文章目录 1 多层感知机&#xff08;全连接神经网络&#xff09;1.1 表示1.2 基本概念1.3 必要组成—激活函数1.4 网络结构设计 2 损失函数2.1 SOFTMAX操作2.2 交叉熵损失函数 3 优化3.1 求导计算过于复杂&#xff1f;3.2 链式法则导致的问题&#xff1f;3.3 梯度下降算法的改进…

八大排序(二)快速排序

一、快速排序的思想 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法&#xff0c;其基本思想为&#xff1a;任取待排序元素序列中的某元素作为基准值&#xff0c;按照该排序码将待排序集合分割成两子序列&#xff0c;左子序列中所有元素均小于基准值&#xff0c;右…

免费的AI写作软件-智能AI写作工具

我们要谈的话题是AI写作&#xff0c;尤其是免费AI写作&#xff0c;以及147SEOAI写作免费工具。您是否曾经为了创作文章而感到煞费苦心&#xff1f;是否一直在寻找一种能够轻松生成高质量文章的方法&#xff1f; 147GPT批量文章生成工具​www.147seo.com/post/2801.html​编辑ht…

Flink TaskManger 内存计算实战

Flink TaskManager内存计算图 计算实例 案例一、假设Task Process内存4GB。 taskmanager.memory.process.size4096m 先排减JVM内存。 JVM Metaspace 固定内存 256mJVM Overhead 固定比例 process * 0.1 4096 * 0.1 410m 得到 Total Flink Memory 4096-256-410 3430m 计…

求生之路2服务器搭建插件安装及详细的游戏参数配置教程windows

求生之路2服务器搭建插件安装及详细的游戏参数配置教程windows 大家好我是艾西&#xff0c;最近研究了下 l4d2&#xff08;求生之路2&#xff09;这款游戏的搭建以及架设过程。今天就给喜欢l4d2这款游戏的小伙伴们分享下怎么搭建架设一个自己的服务器。毕竟自己当服主是热爱游…

华为云云耀云服务器L实例评测|redis漏洞回顾 MySQL数据安全解决 搭建主从集群MySQL 相关设置

前言 最近华为云云耀云服务器L实例上新&#xff0c;也搞了一台来玩&#xff0c;期间遇到过MySQL数据库被攻击的情况&#xff0c;数据丢失&#xff0c;还好我有几份备份&#xff0c;没有造成太大的损失&#xff1b;后来有发现Redis数据库被攻击的情况&#xff0c;加入了redis密…

基于springboot+vue的校园外卖服务系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

【Vue+Element-UI】实现登陆注册界面及axios之get、post请求登录功能实现、跨域问题的解决

目录 一、实现登陆注册界面 1、前期准备 2、登录静态页实现 2.1、创建Vue组件 2.2、静态页面实现 2.3、配置路由 2.4、更改App.vue样式 2.5、效果 3、注册静态页实现 3.1、静态页面实现 3.2、配置路由 3.3、效果 二、axios 1、前期准备 1.1、准备项目 1.2、安装…

原生HTML实现marquee向上滚动效果

实现原理&#xff1a;借助CSS3中animation动画以及原生JS克隆API <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /…

Northstar 量化平台

基于 B/S 架构、可替代付费商业软件的一站式量化交易平台。具备历史回放、策略研发、模拟交易、实盘交易等功能。兼顾全自动与半自动的使用场景。 已对接国内期货股票、外盘美股港股。 面向程序员的量化交易软件&#xff0c;用于期货、股票、外汇、炒币等多种交易场景&#xff…

OpenCV中的HoughLines函数和HoughLinesP函数到底有什么区别?

一、简述 基于OpenCV进行直线检测可以使用HoughLines和HoughLinesP函数完成的。这两个函数之间的唯一区别在于,第一个函数使用标准霍夫变换,第二个函数使用概率霍夫变换(因此名称为 P)。概率版本之所以如此,是因为它仅分析点的子集并估计这些点都属于同一条线的概率。此实…

php文件上传功能(文件上传)

实现文件上传是Web开发中常用的功能之一&#xff0c;而PHP也是支持文件上传的。那么&#xff0c;下面我们就来介绍一下常用的PHP实现文件上传的方法。 使用HTML表单实现文件上传 HTML表单是Web开发中最基本的元素之一&#xff0c;它可以接收用户输入的数据&#xff0c;并通过…

论文阅读_大语言模型_Llama2

英文名称: Llama 2: Open Foundation and Fine-Tuned Chat Models 中文名称: Llama 2&#xff1a;开源的基础模型和微调的聊天模型 文章: http://arxiv.org/abs/2307.09288 代码: https://github.com/facebookresearch/llama 作者: Hugo Touvron 日期: 2023-07-19 引用次数: 11…

C语言数组和指针笔试题(四)(一定要看)

目录 二维数组例题一例题二例题三例题四例题五例题六例题七例题八例题九例题十例题十一 结果 感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接 &#x1f412;&#x1f412;&#x1f412;个人主页 &#x1f978;&#x1f978;&#x1f978;C语言 &#x1f43f;️…

SWC 流程

一个arxml 存储SWC &#xff08;可以存多个&#xff0c;也可以一个arxml存一个SWC&#xff09;一个arxml 存储 composition &#xff08;只能存一个&#xff09;一个arxml 存储 system description (通过import dbc自动生成system) 存储SWC和composition的arxml文件分开&#…