Bitmap的一个简单实现

一、Bitmap简介

Bitmap是一种常用的数据结构,其实就是一个连续的数组,主要是用于映射关系,如映射整数,一位代表一个数,即这里假设Bitmap有100Bytes * 8 这么多的位,那么这里可以映射出来0~799,虽然大于799的数也能够映射,但是在查找时就不能确定该位是某数还是某数加800。为什么会设计这个数据结构,因为在映射大量数据时,这个数据结构可以很好的节省空间,并且有较高的查找效率。所以这种数据结构在海量数据的时候有较广泛的应用。这里还要说明的一点就是,一位代表一个数只是一种应用的方式,还可一扩展到两位代表一个数,还可以记录一些别的需要的信息。参考资料2,3中有一些涉及到Bitmap的面试题,有兴趣的可自行查阅。

二、Bitmap的一种实现

这里仅给出一位映射一个数的情况,比如现在有Bitmap这个数组,那么给定一个数怎么映射呢?比如这个数是23,那么需要在Bitmap数组中的第二十三位设置为1,这里的第二十三位不一定是顺序数的第二十三位(计算机有大端存储和小端存储,可见参考文献1,这个链接可能打不开了,我把整理的pdf放到了代码下载的位置,有兴趣的可自行下载查看),但是这里只要符合一一映射这个关系即可,查找的过程就是你映射过程的逆过程即可。 

三、Bitmap的简单代码实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_SIZE 100

#define QUOTIENT(number) ((number) / (((sizeof(char)) * 8)))
#define REMAINDER(number) ((number) % (((sizeof(char)) * 8)))

int
main(int argc, char const *argv[])
{
	char bitmap[MAX_SIZE];
	memset(bitmap, 0, sizeof(bitmap));
	char *ptr = bitmap;
	int number_in = 0;
	int number_search = 0;
	int i = 0;

	printf("Please input the numbers continuously(less than and not equal %d) "
	"that will be saved in the bit map and enter the number -1 to finish!\n", 
	MAX_SIZE * sizeof(char) * 8);
	while(EOF != (scanf("%d", &number_in)))
	{
		if(-1 == number_in)
			break;

		ptr = bitmap;

		if(MAX_SIZE <= QUOTIENT(number_in))
			return 0;

		for (i = 0; i < QUOTIENT(number_in); ++i)
		{
			ptr++;
		}
		*ptr |= (0x01 << REMAINDER(number_in));
	}

	printf("Please input the numbers continuously(less than and not equal %d) "
	"that will be searched whether in the bit map or not and enter the number -1 to finish!\n", 
	MAX_SIZE * sizeof(char) * 8);
	while(EOF != (scanf("%d", &number_search)))
	{
		if(-1 == number_search)
			break;

		char location = (char)0;
		ptr = bitmap;

		if(MAX_SIZE < QUOTIENT(number_search))
			return 0;
		for (i = 0; i <= QUOTIENT(number_search); ++i)
		{		
			ptr++;
		}
		location = (*ptr) & (location | (0x01 << REMAINDER(number_search)));

		if(0 == location)
			printf("the number %d is not exist!\n", number_search);
		else
			printf("the number %d is exist!\n", number_search);
	}
	
	return 0;
}

四、程序的一点说明

程序的思路非常简单,就是把数对应到数组的某一位上,设置该位为1,查找是查看同样位置的该位是否为1,为1则说明该数存在于Bitmap中,否则不存在。

生成Bitmap和查找一个数之前那个判断非常重要即

if(MAX_SIZE <= QUOTIENT(number_in))

if(MAX_SIZE <= QUOTIENT(number_search))


这个涉及到C语言的一个不安全因素,它可以越界访问/设置内存,所以这里要判断ptr设置的值实在定义的Bitmap数组的内存空间内,虽然这一步不加也不影响程序的运行,但是不建议这么做,因为这样做可能会把有用的内存空间设置值,可能会引起程序或系统崩溃。

五、参考资料

1. Big Endian 和 Little Endian: 

http://ayazh.gjjblog.com/archives/1058846/

2. Bitmap的一些面试题, 十七道海量数据处理面试题与Bit-map详解:
http://blog.csdn.net/v_july_v/article/details/6685962

3. Bitmap的一些面试题,教你如何迅速秒杀掉:99%的海量数据处理面试题:
http://blog.csdn.net/v_july_v/article/details/7382693


说明:

如有错误还请各位指正,欢迎大家一起讨论给出指导。

上述程序完整代码及Big Endian 和 Little Endian的pdf的下载链接:
https://github.com/zeliliu/BlogPrograms/tree/master/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%26%E7%AE%97%E6%B3%95/bitmap

最后更新时间2013-07-02



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值