Bitmap算法原理

标签: 技术荟萃 | 发表时间:2012-10-18 16:22 | 作者:黄言之
出处:http://blog.sina.com.cn/netreview

【什么是 Bit-map

所谓的Bit-map就是用一个bit位来标记某个元素对应的Value, 而Key即是该元素。由于采用了Bit为单位来存储数据,因此在存储空间方面,可以大大节省。

如果说了这么多还没明白什么是Bit-map,那么我们来看一个具体的例子,假设我们要对0-7内的5个元素(4,7,2,5,3)排序(这里假设这些元素没有重复)。那么我们就可以采用Bit-map的方法来达到排序的目的。要表示8个数,我们就只需要8个Bit(1Bytes),首先我们开辟1Byte 的空间,将这些空间的所有Bit位都置为0(如下图:)

clip_image002

然后遍历这5个元素,首先第一个元素是4,那么就把4对应的位置为1(可以这样操作 p+(i/8)|(0x01<<(i%8)) 当然了这里的操作涉及到Big-ending和Little-ending的情况,这里默认为Big-ending),因为是从零开始的,所以要把第五位置为一(如下图):

clip_image004

然后再处理第二个元素7,将第八位置为1,,接着再处理第三个元素,一直到最后处理完所有的元素,将相应的位置为1,这时候的内存的Bit位的状态如下:

clip_image006

然后我们现在遍历一遍Bit区域,将该位是一的位的编号输出(2,3,4,5,7),这样就达到了排序的目的。

Bit-map排序实例

下面的代码给出了一个BitMap的用法:排序。

//定义每个Byte中有8个Bit位
#include <memory.h>
#define BYTESIZE 8
void SetBit(char *p, int posi)
{
for(int i=0; i < (posi/BYTESIZE); i++)
{
p++;
}
*p = *p|(0x01<<(posi%BYTESIZE));// 将该Bit位赋值1,1左移posi%BYTESIZE位,即标识上这一位。
return;
}
void BitMapSortDemo()
{
//为了简单起见,我们不考虑负数
int num[] = {3,5,2,10,6,12,8,14,9};
//BufferLen这个值是根据待排序的数据中最大值确定的
//待排序中的最大值是14,因此只需要2个Bytes(16个Bit)
//就可以了。
const int BufferLen = 2;
char *pBuffer = new char[BufferLen];
//要将所有的Bit位置为0,否则结果不可预知。
memset(pBuffer,0,BufferLen);
for(int i=0;i<9;i++)
{
//首先将相应Bit位上置为1
SetBit(pBuffer,num[i]);
}
//输出排序结果
for(int i=0;i<BufferLen;i++)//每次处理一个字节(Byte)
{
for(int j=0;j<BYTESIZE;j++)//处理该字节中的每个Bit位
{
//判断该位上是否是1,进行输出,这里的判断比较笨。
//首先得到该第j位的掩码(0x01<<j),将内存区中的
//位和此掩码作与操作。最后判断掩码是否和处理后的
//结果相同
if((*pBuffer&(0x01<<j)) == (0x01<<j))
{
printf("%d ",i*BYTESIZE + j);
}
}
pBuffer++;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
BitMapSortDemo();
return 0;
}

Bit-map实用代码

Bit-map基本的代码可以整理如下:

#define BITMAP_SET(map, p)    ((void)(((char*)(map))[(p)/CHAR_BIT] |= 1<<(p)%CHAR_BIT))
#define BITMAP_CLEAR(map, p)    ((void)(((char*)(map))[(p)/CHAR_BIT] &= ~(1<<(p)%CHAR_BIT)))
#define BITMAP_FLIP(map, p)    ((void)(((char*)(map))[(p)/CHAR_BIT] ^= 1<<(p)%CHAR_BIT))
#define BITMAP_TEST(map, p)    (((char*)(map))[(p)/CHAR_BIT] & (1<<(p)%CHAR_BIT))

【适用范围】

可进行数据的快速查找,判重,删除,一般来说数据范围是int的10倍以下

【基本原理及要点】

使用bit数组来表示某些元素是否存在,比如8位电话号码

【扩展】

Bloom filter可以看做是对bit-map的扩展

【问题实例】

1) 已知某个文件内包含一些电话号码,每个号码为 8 位数字,统计不同号码的个数。

8位最多99 999 999,大概需要99m个bit,大概10几m字节的内存即可。 (可以理解为从0-99 999 999的数字,每个数字对应一个Bit位,所以只需要99M个Bit==1.2MBytes,这样,就用了小小的1.2M左右的内存表示了所有的8位数的电话)

2)2.5 亿个整数中找出不重复的整数的个数,内存空间不足以容纳这 2.5 亿个整数。

将bit-map扩展一下,用2bit表示一个数即可,0表示未出现,1表示出现一次,2表示出现2次及以上,在遍历这些数的时候,如果对应位置的值是0,则将其置为1;如果是1,将其置为2;如果是2,则保持不变。或者我们不用2bit来进行表示,我们用两个bit-map即可模拟实现这个 2bit-map,都是一样的道理。


  青春就应该这样绽放   游戏测试:三国时期谁是你最好的兄弟!!   你不得不信的星座秘密

相关 [bitmap 算法 原理] 推荐:

Bitmap算法原理

- - 互联网旁观者
【什么是 Bit-map 】. 所谓的Bit-map就是用一个bit位来标记某个元素对应的Value, 而Key即是该元素. 由于采用了Bit为单位来存储数据,因此在存储空间方面,可以大大节省. 如果说了这么多还没明白什么是Bit-map,那么我们来看一个具体的例子,假设我们要对0-7内的5个元素(4,7,2,5,3)排序(这里假设这些元素没有重复).

bitmap算法简介

- - CSDN博客推荐文章
今天看到海量数据处理算法————bitmap(又称为bitset, 或者bit array), 有意思的算法. C++ 有一个头文件是. bitmap的思想就是数据压缩. 用一个二进制bit(0或者1)去标记某个元素对应的value, 这就是bit + map啊. 由于使用bit单位存储数据, 所以可大大节省内存空间.

Bitmap优化

- - CSDN博客推荐文章
一个进程的内存可以由2个部分组成:. dalvik就是我们平常说的. java堆,我们创建的对象是在这里面分配的,而. Java后,以后这块内存即使释放后,也只能给. Java突然占用了一个大块内存,. malloc进行内存分配的,占用的是. C的内存,这个也就说明了,上述的. 4MBitmap无法生成的原因,.

Bitmap的秘密

- - 博客园_知识库
  之前已经参加过几次QCon峰会,不过今年QCon 2014 上海峰会对我来说比较特别,不再只是一名听众,而是第一次登台演讲. 感觉的确不太一样,一来是身份从听众变成了讲师,二来是因为成了讲师,让我接触到更多的业内朋友,也遇到了更多的提问、咨询. 会后已经有一段时间了,还有朋友提出想了解更多的技术知识.

Redis中bitmap的妙用

- - IT瘾-tuicool
在Redis中我们经常用到set,get等命令,细心的你有没有发现,还有几个相似的命令叫setbit,getbit,它们是用来干嘛的. 就是通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身. 我们知道8个bit可以组成一个Byte,所以bitmap本身会极大的节省储存空间.

bitmap索引的深入研究

- - 数据库 - ITeye博客
位图(bitmap)索引是另外一种索引类型,它的组织形式与B树索引相同,也是一棵平衡树. 与B树索引的区别在于叶子节点里存放索引条目的方式不同. 从前面我们知道,B树索引的叶子节点里,对于表里的每个数据行,如果被索引列的值不为空的,则会为该记录行在叶子节点里维护一个对应的索引条目. 而位图索引则不是这样,其叶子节点里存放的索引条目如下图所示.

AndroidのBitmap之大图片优化

- - 博客园_首页
不解释大家懂得,在listview 或grid或viewpager等大量大尺寸图片时,会造成OOM. 这里是优化图片内存的一个方法,注释写的很 明确... public Bitmap getBitmapFromNet(final String url,final int width,final int height){//从网络下载图片.

redis 用setbit(bitmap)统计活跃用户

- - 编程语言 - ITeye博客
Redis支持对String类型的value进行基于二进制位的置位操作. 通过将一个用户的id对应value上的一位,通过对活跃用户对应的位进行置位,就能够用一个value记录所有活跃用户的信息. 如下图所未,下图中的bitmap有9个位被置为1,表示这9个位上对应的用户是今天的活跃用户. 其中第15位表示uid为15的用户,第一位表示uid为0的用户.

RSA算法原理(二)

- - 阮一峰的网络日志
上一次,我介绍了一些 数论知识. 有了这些知识,我们就可以看懂 RSA算法. 这是目前地球上最重要的加密算法. 我们通过一个例子,来理解RSA算法. 假设 爱丽丝要与鲍勃进行加密通信,她该怎么生成公钥和私钥呢. 第一步,随机选择两个不相等的质数p和q. (实际应用中,这两个质数越大,就越难破解.

RSA算法原理(一)

- - 阮一峰的网络日志
如果你问我,哪一种 算法最重要. 我可能会回答 "公钥加密算法". 因为它是计算机通信安全的基石,保证了加密数据不会被破解. 你可以想象一下,信用卡交易被破解的后果. 进入正题之前,我先简单介绍一下,什么是"公钥加密算法". 1976年以前,所有的加密方法都是同一种模式:.   (1)甲方选择某一种加密规则,对信息进行加密;.