数据结构--位图 BitMap

文章目录

    • 1. 位图
    • 2. 位图代码
    • 3. 布隆过滤器 Bloom Filter
    • 4. 总结

1. 位图

我们有1千万个整数,整数的范围在1到1亿之间。如何快速查找某个整数是否在这1千万个整数中呢?

  • 当然,这个问题可以用散列表来解决。可以使用一种特殊的散列表,那就是位图
  • 申请一个大小为1亿、布尔类型(true或者false)的数组。将这1千万个整数作为数组下标,将对应的数组值设置成true。比如,整数5对应下标为5的数组值设置为true,也就是array[5]=true。
  • 查询某个整数K是否在这1千万个整数中的时候,只需将array[K]取出来,看是否等于true。如果等于true,那说明1千万整数中包含这个整数K;相反,就表示不包含这个整数K。
  • 不过,很多语言中提供的布尔类型,大小是1个字节的,并不能节省太多内存空间。实际上,表示true和false,只需要**一个二进制位(bit)**就可以了。
  • 我们可以借助编程语言中提供的数据类型,比如int、long、char等类型,通过位运算,用其中的某个位表示某个数字。

2. 位图代码

#include <iostream>
#include <cstring>
using namespace std;
class BitMap
{char *bytes;    //char是1字节,8位int nbits;
public:BitMap(int n){nbits = n;bytes = new char [nbits/8 + 1];memset(bytes, 0, (nbits/8+1)*sizeof(char));}~BitMap(){delete [] bytes;}void set(int k){if(k > nbits)return;int byteIndex = k/8;int bitIndex = k%8;bytes[byteIndex] |= (1<<bitIndex);}bool get(int k){if(k > nbits)return false;int byteIndex = k/8;int bitIndex = k%8;return (bytes[byteIndex] & (1 << bitIndex)) != 0;}void print(){for(int i = 15; i >= 0; --i)cout << get(i) << " ";}
};
int main()
{BitMap bm(8);bm.set(8);cout << bm.get(8) << endl;bm.print();return 0;
}

比如上面例子,如果用散列表存储这1千万的数据,数据是32位的整型数,也就是需要4个字节的存储空间,那总共至少需要40MB的存储空间。如果通过位图的话,数字范围在1到1亿之间,只需要1亿个二进制位,1亿/8/1024/1024 = 12, 也就是12MB左右的存储空间就够了。

不过,这里我们有个假设,就是数字范围不是很大。如果数字的范围很大,数字范围不是1到1亿,而是1到10亿,那位图的大小就是10亿个二进制位,也就是120MB的大小,消耗的内存空间不降反增

怎么办?请布隆过滤器登场!

3. 布隆过滤器 Bloom Filter

  • 布隆过滤器就是为了解决刚刚这个问题,对位图这种数据结构的一种改进。

还是刚刚那个例子,数据个数是1千万,数据的范围是1到10亿。

  • 布隆过滤器的做法是,我们仍然使用一个1亿个二进制大小的位图,然后通过哈希函数,对数字进行处理,让它落在这1到1亿范围内。比如我们把哈希函数设计成f(x) = x%n。其中,x表示数字,n表示位图的大小(1亿),也就是,对数字跟位图的大小进行取模求余。

  • 哈希函数会存在冲突的问题,为了降低冲突概率,可以设计一个复杂点、随机点的哈希函数。除此之外,还有其他方法吗?

  • 我们来看布隆过滤器的处理方法。既然一个哈希函数可能会存在冲突,那用多个哈希函数一起定位一个数据,是否能降低冲突的概率呢?

  • 使用 K 个哈希函数,对同一个数字进行求哈希值,那会得到K个不同的哈希值,我们分别记作X1,X2,X3,……Xk 。我们把这 K 个数字作为位图中的下标,将对应的BitMap[X1],BitMap[X2],BitMap[X3],……BitMap[Xk]都设置成true,也就是说,我们用 K 个二进制位,来表示一个数字的存在。

  • 当我们要查询某个数字是否存在的时候,我们用同样的 K 个哈希函数,对这个数字求哈希值,分别得到Y1,Y2,Y3,……Yk 。看这 K 个哈希值,对应位图中的数值是否都为true,都是true,这个数字存在,任意一个不为true,说明这个数字不存在。
    在这里插入图片描述
    对于两个不同的数字,经过 K 个哈希函数处理之后,K 个哈希值都相同的概率就非常低了。尽管采用 K 个哈希函数之后,两个数字哈希冲突的概率降低了,但是,这种处理方式又带来了新的问题,那就是容易误判。看下面例子。
    在这里插入图片描述

  • 布隆过滤器的误判有一个特点,那就是,它只会对存在的情况有误判

  • 如果某个数字经过布隆过滤器判断不存在,那说明这个数字真的不存在,不会误判

  • 如果某个数字经过布隆过滤器判断存在,有可能误判,有可能并不存在。不过,只要我们调整哈希函数的个数、位图大小跟要存储数字的个数之间的比例,那就可以将这种误判的概率降到非常低。

  • 尽管布隆过滤器会存在误判,但是,这并不影响它发挥大作用。很多场景对误判有一定的容忍度

4. 总结

布隆过滤器非常适合这种不需要100%准确的允许存在小概率误判的大规模判重场景。比如统计一个大型网站的每天的UV数,也就是每天有多少用户访问了网站,就可以使用布隆过滤器,对重复访问的用户,进行去重。

布隆过滤器的误判率,主要跟哈希函数的个数位图的大小有关。往布隆过滤器中不停地加入数据之后,位图中不是true的位置就越来越少了,误判率就越来越高了。所以,对于无法事先知道要判重的数据个数的情况,我们需要支持自动扩容的功能。

当布隆过滤器中,数据个数与位图大小比例超过某个阈值的时候,我们就重新申请一个新的位图。后面来的新数据,会被放置到新的位图中。但是,如果我们要判断某个数据是否在布隆过滤器中已经存在,我们就需要查看多个位图,相应的执行效率就降低了一些。

位图、布隆过滤器应用如此广泛,很多编程语言都已经实现了。比如 Java 中的 BitSet 类就是一个位图,Redis 也提供了 BitMap 位图类,Google 的 Guava 工具包提供了BloomFilter 布隆过滤器的实现。

课后思考
1.假设我们有1亿个整数,数据范围是从1到10亿,如何快速并且省内存地给这1亿个数据从小到大排序?

传统做法:1亿个整数,存储需要400M空间
位图算法:数字范围是1到10亿,用位图存储125M就够了,然后将1亿个数字依次添加到位图中,再将位图按下标从小到大输出值为1的下标,排序就完成了,时间复杂度为O(n)

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

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

相关文章

领域应用 | 企业效益最大化的秘密:知识图谱

本文转载自公众号&#xff1a;TigerGraph。凡是有关系的地方都可以用知识图谱。知识图谱知识图谱是用节点和关系所组成的图谱&#xff0c;为真实世界的各个场景直观地建模&#xff0c;运用“图”这种基础性、通用性的“语言”&#xff0c;“高保真”地表达这个多姿多彩世界的各…

国家一级职业资格证书 计算机类有哪些

当前bai&#xff0c;计算机证书考试多种du多样&#xff0c;水平参差不齐。比较正规且得到社会zhi认可的dao计算机证书考试有以下几种&#xff1a;全国计算机应用软件人员水平考试、计算机等级考试、计算机及信息高新技术考试、计算机应用水平测试和各种国外著名大计算机公司组织…

阿里P8架构师谈:分布式系统全局唯一ID简介、特点、5种生成方式

什么是分布式系统唯一ID 在复杂分布式系统中&#xff0c;往往需要对大量的数据和消息进行唯一标识。 如在金融、电商、支付、等产品的系统中&#xff0c;数据日渐增长&#xff0c;对数据分库分表后需要有一个唯一ID来标识一条数据或消息&#xff0c;数据库的自增ID显然不能满足…

朴素贝叶斯算法--过滤垃圾短信

文章目录1. 基于黑名单过滤2. 基于规则过滤3. 基于概率统计过滤4. 总结上一节我们讲到&#xff0c;如何用位图、布隆过滤器&#xff0c;来 过滤重复数据。今天&#xff0c;我们再讲一个跟过滤相关的问题&#xff0c;如何过滤垃圾短信&#xff1f;1. 基于黑名单过滤 可以维护一…

2020深度文本匹配最新进展:精度、速度我都要!

文 | QvQ编 | 兔子酱在过去的几年里&#xff0c;信息检索(IR)领域见证了一系列神经排序模型的引入&#xff0c;这些模型多是基于表示或基于交互的&#xff0c;亦或二者的融合。然鹅&#xff0c;模型虽非常有效&#xff0c;尤其是基于 PLMs 的排序模型更是增加了几个数量级的计算…

开源开放 | Gowild 狗尾草“七律”知识图谱进入 OpenKG,开放 8000 万中文百科知识三元组数据...

项目网站: https://ai.gowild.cn/kgOpenKG发布地址: http://openkg.cn/dataset/7lore狗尾草科技&#xff1a;https://www.gowild.cn1.七律开放知识图谱简介作为人工智能技术的重要分支&#xff0c;知识图谱自2012年被提出并成功应用后&#xff0c;就获得了迅速发展&#xff0c;…

向量空间 Vector Space -- 推荐系统

文章目录1. 算法解析2. 基于相似用户做推荐3. 基于相似歌曲做推荐4. 总结音乐App的功能越来越强大&#xff0c;不仅可以自己选歌听&#xff0c;还可以根据你听歌的口味偏好&#xff0c; 给你推荐可能会喜爱的音乐&#xff0c;有时候&#xff0c;推荐的还非常适合你的口味。1. 算…

阿里P8架构师谈:分布式事务的解决方案,以及原理、总结

分布式事务是企业集成中的一个技术难点&#xff0c;也是每一个分布式系统架构中都会涉及到的一个东西&#xff0c;特别是在这几年越来越火的微服务架构中&#xff0c;几乎可以说是无法避免&#xff0c;本文就围绕分布式事务各方面与大家进行介绍。 事务 1.1 什么是事务 数据库…

美团NLP中心算法实习生内推啦!

星标/置顶小屋&#xff0c;带你解锁最萌最前沿的NLP、搜索与推荐技术部门介绍搜索与NLP部是美团人工智能技术研发的核心团队&#xff0c;致力于打造高性能、高扩展的搜索引擎和领先的自然语言处理核心技术和服务能力&#xff0c;依托搜索排序&#xff0c;NLP&#xff08;自然语…

B+树 -- MySQL数据库索引

文章目录1. 定义清楚问题2. 尝试学过的数据结构解决问题3. 改造二叉查找树来解决问题4. 总结为了加速数据库中数据的查找速度&#xff0c;我们常对表中数据创建索引。数据库索引是如何实现的呢&#xff1f;底层使用的是什么数据结构和算法呢&#xff1f; 1. 定义清楚问题 如何…

创建python的虚拟环境(图文教程),并使用。

创建python的虚拟环境 第一步&#xff1a;打开anaconda命令行&#xff0c;即打开anaconda prompt。 base的主环境切换到虚拟环境nlp (base) C:\Users\user>conda env list 查看环境列表 (base) C:\Users\user>conda create -n nlp python 创建一个虚拟环境&#xff0…

领域应用 | 到底什么时候使用图数据库?

本文转载自公众号&#xff1a;TigerGraph。图数据库作为近两年快速发展的新型数据受到了市场极大的关注。但对于很多行业而言&#xff0c;图数据库还是一个很新的概念&#xff0c;企业管理人员和技术人员面临着同样的问题&#xff1a;企业的业务适不适合使用图&#xff1f;到底…

常用的后端性能优化六种方式:缓存化+服务化+异步化等

后端优化的六种方法&#xff1a; 1.硬件升级 硬件问题对性能的影响不容忽视。 举一个例子&#xff1a;一个DB集群经常有慢SQL报警&#xff0c;业务排查下来发现SQL都很简单&#xff0c;该做的索引优化也都做了。后来DBA同学帮忙定位到问题是硬件过旧导致&#xff0c;将机械硬…

有钱可以多任性?OpenAI提出人肉模型训练,文本摘要全面超越人类表现!

文 | 小轶背景三个多月前&#xff0c;OpenAI的GPT-3在NLP界掀起轩然大波。就在上周&#xff0c;视金钱如粪土的OpenAI团队又在文本摘要方面推出了最新力作&#xff0c;全方位超越人类表现。其亮点在于&#xff1a;以人类偏好替代自动化评测方法&#xff08;如ROUGE、BLUE&#…

数据挖掘第一次作业

我先大概写了写&#xff0c;还有一些读过的论文没有往上放&#xff0c;一些论文之间的联系线条没有搞出来。 就先这样吧&#xff01;有空再搞&#xff0c;我现在想去玩板子啦&#xff01;

A*搜索算法--游戏寻路

文章目录1. 算法解析2. 总结仙剑奇侠传这类MMRPG游戏中&#xff0c;有人物角色 自动寻路功能。当人物处于游戏地图中某位置时&#xff0c;点击另一个相对较远的位置&#xff0c;人物就会自动地绕过障碍物走过去。这个功能是怎么实现的呢&#xff1f;1. 算法解析 这是一个非常典…

阿里P8架构师谈:应用后端+移动端的性能优化指标,以及性能优化方法

性能优化专题 阿里P8架构师谈&#xff1a;MySQL数据库的索引原理、与慢SQL优化的5大原则 阿里P8架构师谈&#xff1a;Web前端、应用服务器、数据库SQL等性能优化总结 大型网站Web前端优化最佳实践&#xff0c;以及最全优化工具集锦 阿里P8架构师谈&#xff1a;多线程、架构、…

无主题

厦门月亮少 20191003 之前突然遇到个bug&#xff0c;解决好久无果&#xff0c;开始干点别的事情&#xff0c;大约四天后的今天&#xff0c;我打开程序想解决一下&#xff0c;然后&#xff0c;调试半天无果&#xff0c;妈妈突然微信和我聊天了&#xff0c;聊完以后往终端一瞥&a…

PyTorch Trick集锦

文 | z.defying知乎来源 | https://zhuanlan.zhihu.com/p/76459295前言本文整理了13则PyTorch使用的小窍门&#xff0c;包括了指定GPU编号、梯度裁剪、扩展单张图片维度等实用技巧&#xff0c;能够帮助工作者更高效地完成任务。1、指定GPU编号2、查看模型每层输出详情3、梯度裁…

论文浅尝 | 利用推理链进行视觉问题回答

论文笔记整理&#xff1a;吴杨&#xff0c;浙江大学计算机学院&#xff0c;知识图谱、NLP方向。http://papers.nips.cc/paper/7311-chain-of-reasoning-for-visual-question-answering.pdf动机在视觉问题回答中&#xff0c;较为复杂的问题经常需要多步骤的推理才能够回答&#…