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
Bitmap的一个简单实现的更多相关文章
- 一个简单的QQ隐藏图生成算法 通过jQuery和C#分别实现对.NET Core Web Api的访问以及文件上传
一个简单的QQ隐藏图生成算法 隐藏图不是什么新鲜的东西,具体表现在大部分社交软件中,预览图看到的是一张图,而点开后看到的又是另一张图.虽然很早就看到过这类图片,但是一直没有仔细研究过它的原理,今天 ...
- Android官方教程翻译(3)——创建一个简单的用户界面
转载请注明出处:http://blog.csdn.net/dawanganban/article/details/9839523 Building a Simple User Interface 创建 ...
- 制作一个简单的WPF图片浏览器
原文:制作一个简单的WPF图片浏览器 注:本例选自MSDN样例,并略有改动.先看效果: 这里实现了以下几个功能:1. 对指定文件夹下所有JPG文件进行预览2. 对选定图片进行旋转3. 对选定图片 ...
- 哪种缓存效果高?开源一个简单的缓存组件j2cache
背景 现在的web系统已经越来越多的应用缓存技术,而且缓存技术确实是能实足的增强系统性能的.我在项目中也开始接触一些缓存的需求. 开始简单的就用jvm(java托管内存)来做缓存,这样对于单个应用服务 ...
- 在Openfire上弄一个简单的推送系统
推送系统 说是推送系统有点大,其实就是一个消息广播功能吧.作用其实也就是由服务端接收到消息然后推送到订阅的客户端. 思路 对于推送最关键的是服务端向客户端发送数据,客户端向服务端订阅自己想要的消息.这 ...
- ASP.NET Aries 入门开发教程2:配置出一个简单的列表页面
前言: 朋友们都期待我稳定地工作,但创业公司若要躺下,也非意念可控. 若人生注定了风雨飘摇,那就雨中前行了. 最机开始看聊新的工作机会,欢迎推荐,创业公司也可! 同时,趁着自由时间,抓紧把这系列教程给 ...
- 计算机程序的思维逻辑 (60) - 随机读写文件及其应用 - 实现一个简单的KV数据库
57节介绍了字节流, 58节介绍了字符流,它们都是以流的方式读写文件,流的方式有几个限制: 要么读,要么写,不能同时读和写 不能随机读写,只能从头读到尾,且不能重复读,虽然通过缓冲可以实现部分重读,但 ...
- 如何开发一个简单的HTML5 Canvas 小游戏
原文:How to make a simple HTML5 Canvas game 想要快速上手HTML5 Canvas小游戏开发?下面通过一个例子来进行手把手教学.(如果你怀疑我的资历, A Wiz ...
- CSharpGL(24)用ComputeShader实现一个简单的图像边缘检测功能
CSharpGL(24)用ComputeShader实现一个简单的图像边缘检测功能 效果图 这是红宝书里的例子,在这个例子中,下述功能全部登场,因此这个例子可作为使用Compute Shader的典型 ...
随机推荐
- final、finally、finalize差异
final.finally.finalize差异 1.final修饰符 它代表了一类是完美的类,它不能被继承,因此.一个类不能既被标记为final类别.同一时间被标记为abstract. 将变量或者函 ...
- AngularJS + CoffeeScript
AngularJS + CoffeeScript 前端开发环境配置详解 AngularJS 号称 '第一框架' ('The first framework') 确实是名不虚传.由其从jQuery中完全 ...
- PHP jpgraph的一点小提示(附安装方法)
PHP中的GD库本身是一套很强大的绘图库了,绘制的图像基本可以满足日常要求,但强大规强大,还是不够方便哈,因为强大方便的基于PHP的GD库的jpgraph也就诞生啦! PHP默认是不启用GD库的,因为 ...
- c#万能视频播放器(附代码)
原文:c#万能视频播放器(附代码) c#万能视频播放器 本人之前很多的文章中均提到了使用libvlc为播放器内核制作的播放器,也许有些朋友对此感兴趣,于是我用c#写了一个调用libvlc api实现的 ...
- JAVA学习课第五十三届 — IO流程(七)File打靶 & Properties设置
一个.锻炼 深度遍历目录 深度遍历非常自然而然想到递归,而递归就非常自然的想到事实上现的底层算法是栈 对指定文件夹下列出全部内容(包括子文件夹的内容) PS:建议不要遍历C盘 import java. ...
- style、currentStyle、getComputeStylel的使用
(1)js中使用obj.style的用法,是为了获得内联样式,即style属性中的值. 如果想获取obj.style.display,但内联样式表中没有定义display,那么将返回一个空的字符串. ...
- MvcPager分页控件以适用Bootstrap
随笔- 9 文章- 0 评论- 33 修改MvcPager分页控件以适用Bootstrap 效果(含英文版,可下载) 软件开发分页效果必不可少,对于Asp.Net MVC 而言,MvcPag ...
- 读书笔记—CLR via C#章节11-13
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...
- 领域模型(Domain Model)
领域模型(Domain Model) 一:面向对象设计中最简单的部分与最难的部分 如果说事务脚本是 面向过程 的,那么领域模型就是 面向对象 的.面向对象的一个很重要的点就是:“把事情交给最适合的类去 ...
- 30个HTML初学者建议
The most difficult aspect of running Nettuts+ is accounting for so many different skill levels. If w ...