算法原理

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. LyScript 计算片段Hash并写出Excel

    本案例将学习运用LyScript计算特定程序中特定某些片段的Hash特征值,并通过xlsxwriter这个第三方模块将计算到的hash值存储成一个excel表格,本例中的知识点可以说已经具备了简单的表 ...

  2. XXE注入详解

    XML介绍 XML全称可扩展标记语言(EXtensible Markup Language),XML跟HTML格式类似,但是作用不同,XML侧重于数据传输,HTML注重于标记语言,也就是说XML其实是 ...

  3. iOS安装包瘦身总结

    前段时间APP要做资源压缩,需要把项目中使用的所有图片资源进行压缩,以减小APP安装包体积.想着既然压缩APP资源是为了缩小APP体积,那么来一遍APP整体瘦身流程并做一下总结吧. 整个过程分三步: ...

  4. Softmax偏导及BP过程的推导

    Softmax求导 其实BP过程在pytorch中可以自动进行,这里进行推导只是强迫症 A Apart证明softmax求导和softmax的BP过程 本来像手打公式的,想想还是算了,引用部分给出la ...

  5. 初步上手Git软件及GitHub平台:基本操作方法

      本文介绍Git软件与GitHub平台的基本内容.使用方法与应用场景等. 目录 1 初步介绍 2 使用方法 2.1 GitHub配置 2.2 Git配置 2.3 代码上传至GitHub 1 初步介绍 ...

  6. mybatis SQL in() 为什么要在 mapper.xml里 用 foreach

    结论: 若存在 in () 语句,要使用 #{} 预编译入参的方式,需要在 mapper.xml里 使用 foreach ======================================= ...

  7. Linux-Shell变量的算术运算

    一.算术运算符 1.+.- 求和. a+b   a-b 2. *./.% 求乘积,商,余数    a*b   a/b    a/b 3.** 幂运算,例如 3**3 是求 3 的立方,即 27 4. ...

  8. 【译】.NET 8 网络改进(二)

    原文 | Máňa,Natalia Kondratyeva 翻译 | 郑子铭 修改 HttpClient 日志记录 自定义(甚至简单地关闭)HttpClientFactory 日志记录是长期请求的功能 ...

  9. 错误发布--如何配置最新的JDK21

    如何配置最新的JDK21 时间:2024/2/3 官网 www.oracle.com 找到对应版本JDK21 可选择语言翻译版本 根据需求选择合适JDK版本.操作系统.位数 三个安装包格式:最简洁的是 ...

  10. Swoole从入门到入土(20)——WebSocket服务器[协程版本]

    本篇让我们先用一段示例代码开路: <?php Co\run(function () { $server = new Co\Http\Server('0.0.0.0', 9501, false); ...