算法原理

BitMap的基本思想就是用一个bit位来标记某个元素对应的Value,而Key即是该元素。由于采用了Bit为单位来存储数据,因此可以大大节省存储空间

BitMap可以看成一种数据结构

假设有这样一个需求:在20亿个随机整数中找出某个数m是否存在其中,并假设32位操作系统,4G内存。

在Java中,int占4字节,1字节=8位(1 byte = 8 bit)。

如果每个数字用int存储,那就是20亿个int,因而占用的空间约为 (2000000000*4/1024/1024/1024)≈7.45G

如果按位存储就不一样了,20亿个数就是20亿位,占用空间约为 (2000000000/8/1024/1024/1024)≈0.233G

优点和缺点

优点:由于采用了Bit为单位来存储数据并建立映射关系来查找位置,因此可以大大减少存储空间,加快在大量数据中查询的时间。(有点哈希表的意思,但哈希中的value值数据类型可以丰富多样,而BitMap最终查到的value只能表示简单的几种状态。)

缺点:BitMap中的查询结果(value)能表达的状态有限,且所有的数据不能重复。即不可对重复的数据进行排序和查找

算法实现(C#)

.NET中已经实现了BitMap的数据结构——BitArray,建议使用BitMap算法解决问题时直接使用官方的BitArray

我参照.NET源码实现了一个简化版的BitMap,以int数组存储位值(最多存21亿个位值),代码如下:

    class BitMap
{
public int Length{ get{ return m_length;}
}
private int[] m_array;
private int m_length; public BitMap(int length): this(length, false) { } //索引根据需求添加
public bool this[int index]
{
get
{
return Get(index);
}
set
{
Set(index,value);
}
} //分配空间以容纳长度位值, 位数组中的所有值都设置为defaultValue。
public BitMap(int length, bool defaultValue)
{
if (length < 0) {
throw new ArgumentOutOfRangeException("length", "长度值不能小于0");
} int arrayLength = length > 0 ? (((length - 1) / 32) + 1) : 0;
m_array = new int[arrayLength];
m_length = length; int fillValue = defaultValue ? unchecked(((int)0xffffffff)) : 0;
for (int i = 0; i < m_array.Length; i++) {
m_array[i] = fillValue;
}
} //返回位置索引处的位值。
public bool Get(int index) {
if (index < 0 || index >= Length) {
throw new ArgumentOutOfRangeException("index", "索引值超出范围");
}
return (m_array[index / 32] & (1 << (index % 32))) != 0;
} //将位置索引处的位值设置为value。
public void Set(int index, bool value) {
if (index < 0 || index >= Length) {
throw new ArgumentOutOfRangeException("index", "索引值超出范围");
} if (value) {
m_array[index / 32] |= (1 << (index % 32));
} else {
m_array[index / 32] &= ~(1 << (index % 32));
}
}
}

算法应用

问题1:给40亿个不重复的unsigned int的整数,没有排过序,然后再给一个数,如果快速判断这个数是否在那40亿个数当中。(解决海量数据中的查询问题

问题1解法:建立一个位集合,全部初始化为0。遍历40亿个不重复的整数,通过上述提供的一种映射(每个不重复的整数映射到给定的位)找到其位的位置,标记为1。判断这个数是否在大整数集合中,即通过映射关系计算此整数的位位置,检查是否为1,若为1,则存在,若为0,则不存在

问题2:数据库里存了很多800电话号码,数量特别大,以至于内存放不下,如何排序,时间比空间更重要?电话号码类似于800-810-5555。(高效排序

问题2解法:其实就是不重复的任意7位数及其之内的排序问题。我们用1位来表示电话是否出现,遍历整个电话号序列,设置相应的位,遍历位图收集位被设置的号码即可。查看上述的实现代码

参考文章

算法系列-bitmap算法详解和实现——CSDN

Bitmap简介——博客园

经典算法系列之(一) - BitMap——简书

BitArray——.NET源码

简单实用算法——位图算法(BitMap)的更多相关文章

  1. 【位图算法】什么是BitMap

    目录 1. 位图算法的简单原理 2. BitMap的开源实现 3. 使用案列 BitMap算法的核心思想是用bit数组来记录0-1两种状态,然后再将具体数据映射到这个比特数组的具体位置,这个比特位设置 ...

  2. 从一道高大上的面试题来学习位图算法BitMap

    今天我偶然刷到了一篇文章,"华为二面:一个文件里面有5亿个数据,一行一个,没有重复的,进行排序".不知道又是哪个无良媒体瞎起的标题,夺人眼球. 不过说归说,这题听着就很高大上,5亿 ...

  3. js实现两种实用的排序算法——冒泡、快速排序

      分类:js (4443) (0) 零:数据准备,给定数组arr=[2,5,4,1,7,3,8,6,9,0]; 一:冒牌排序 1思想:冒泡排序思想:每一次对比相邻两个数据的大小,小的排在前面,如果前 ...

  4. 实用拜占庭容错算法PBFT

    实用拜占庭容错算法PBFT 实用拜占庭容错算法PBFT 96 乔延宏 2017.06.19 22:58* 字数 1699 阅读 4972评论 0喜欢 11 分布式架构遭遇的问题 分布式架构会遭遇到以下 ...

  5. 【算法篇】Bitmap 算法

    首先,什么是Bitmap算法(位图算法)呢? 一:定义: Bit map就是用一个bit位来标记某个元素对应的Value, 而Key即是该元素.使用Bit为用来存储数据的单位, 可以大大节省存储空间. ...

  6. LeetCode-Repeated DNA Sequences (位图算法减少内存)

    Repeated DNA Sequences All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, ...

  7. 简单易学的机器学习算法——EM算法

    简单易学的机器学习算法——EM算法 一.机器学习中的参数估计问题 在前面的博文中,如“简单易学的机器学习算法——Logistic回归”中,采用了极大似然函数对其模型中的参数进行估计,简单来讲即对于一系 ...

  8. 简单的理解deflate算法

    简单的理解deflate算法 最近做压缩算法. 用到了deflate压缩算法,  找了很多资料,  这篇文章算是讲的比较易懂的, 这篇文章不长,但却浅显易懂, 基本上涵盖了我想要知道的所有要点. 翻译 ...

  9. 简单易学的机器学习算法—SVD奇异值分解

    简单易学的机器学习算法-SVD奇异值分解 一.SVD奇异值分解的定义     假设M是一个的矩阵,如果存在一个分解: 其中的酉矩阵,的半正定对角矩阵,的共轭转置矩阵,且为的酉矩阵.这样的分解称为M的奇 ...

  10. 简单易学的机器学习算法—基于密度的聚类算法DBSCAN

    简单易学的机器学习算法-基于密度的聚类算法DBSCAN 一.基于密度的聚类算法的概述 我想了解下基于密度的聚类算法,熟悉下基于密度的聚类算法与基于距离的聚类算法,如K-Means算法之间的区别.    ...

随机推荐

  1. C/C++ 数据结构与算法笔记

    实现顺序表 #include <stdio.h> #include <stdlib.h> #define MaxSize 10 int Insert_Elem(int Arra ...

  2. LeetCode刷题日记2020/8/24

    题目描述 给定一个非空的字符串,判断它是否可以由它的一个子串重复多次构成.给定的字符串只含有小写英文字母,并且长度不超过10000. 示例 1: 输入: "abab" 输出: Tr ...

  3. Nginx的反向代理做负载均衡

    对于一个大型网站,随着网站的访问量快速增长,单台服务器很难再支撑起需要,所以我们会购置多个服务器来满足业务量的需求,然后再利用Nginx提供的反向代理功能,来实现多台服务器间的协作功能,提高网站的处理 ...

  4. Linux进程通信-POSIX IPC

    前言 Linux POSIX IPC的可移植性是不如System V IPC的,但是我们只用Linux,并且内核版本高于2.6.6的话就不存在该问题了.也因为POSIX IPC出现的比较晚,借鉴了sy ...

  5. 【可观测性系列】 OpenTelemetry Collector的部署模式分析

    作者简介:大家好,我是蓝胖子 ️博客首页:主页蓝胖子的编程梦 ️热门专题:我的服务监控实践 ,500行代码手写Docker **每日一句:白日莫闲过,青春不再来 大家好,我是蓝胖子,在前面我介绍了下O ...

  6. 小知识:Oracle中的层次查询

    使用Oracle中的start with .. connect by prior ..语句可以轻松实现. 下面通过scott用户下的emp来做演示,使用自己的一个19c测试环境,结果发现默认并没有sc ...

  7. 思维分析逻辑 4 DAY

    目录 竞品分析 波特五力模型 竞品分析步骤 分析目的 对比分析 初步结论 活动营销分析 用户增长分析 用户增长基本模型 渠道思维(前期) 用户思维(中期) ROI思维(后期) 增长思维 北极星指标:一 ...

  8. JS LeetCode 1423. 可获得的最大点数简单题解

    壹 ❀ 引 最近也是浮躁的很,一篇redux的文章写了三千多字才算写了一半...写的泪目了.还是刷刷算法静下心,顺带记录下算法做题过程吧.今天的题来自LeetCode每日打卡,题目出自LeetCode ...

  9. NC19872 [AHOI2005]SHUFFLE 洗牌

    题目链接 题目 题目描述 为了表彰小联为Samuel星球的探险所做出的贡献,小联被邀请参加Samuel星球近距离载人探险活动. 由于Samuel星球相当遥远,科学家们要在飞船中度过相当长的一段时间,小 ...

  10. Codeforces Round #824 (Div. 2) A-E

    比赛链接 A 题解 知识点:贪心,数学. 注意到三段工作时间一共 \(n-3\) 天,且天数实际上可以随意分配到任意一段,每段至少有一天,现在目的就是最大化段差最小值. 不妨设 \(l_1<l_ ...