位图应用
来源:互联网 发布:手游网络加速器排行 编辑:程序博客网 时间:2024/06/06 10:52
一、背景介绍
本文主要是对编程珠玑中第一章的学习总结。问题背景大致如下:一个最多包含n个正整数的文件,每个数都小于n,其中n=10^7,同时所有的正整数不重复出现。现在需要按升序将所有的整数输出,约束条件是最多有1MB的内存空间可用,但磁盘空间充足。
如果按通常的处理的方法,使用int类型(32位)存储整数,这样1MB的空间可存储10^6B/4B,即约250000个整数,虽然不能同时对所有的数据进行排序。但也可以采取多趟遍历磁盘的方法完成排序工作,但却IO开销大耗时多。于是文中便提出了利用位图(位向量)的方法来解决问题。
二、位图实现
1、实现介绍
例如要表示集合{1,2,3,5,8,13},可采用20位的字符串“01110100100001000000”表示。在问题中每个7位的十进制数表示一个小于1000万的整数,于是我们可以使用一个具有1000万个位的字符串来表示这个文件,其中当且仅当整数i在文件中存在时,第i位为1。
2、C语言实现
由于C语言中没有实现位图的数据结构(c++中有bitset集合),需要通过位运算来实现。下面的C语言程序采用了int来实现位图。
假设总的位图位数为N(题设为1000万),则需要的int数组的位数为(N/32 + 1),所以定义了数组int a[N/32 + 1]。
对于逻辑上的第i位,其存储的位置则为第i/32(位运算采用i>>5,即将i右移5位)个int位置,位位置为i%32(位运算采用i&0x1F实现,即i与数31进行“与”运算)。
所以对逻辑上第i位置1(函数set)为:a[i>>5 ] = a[i>>5] | 1<<(i&0x1F)。即将1左移(i&0x1F)位后再和a[i>>5]进行“或”运算。例如当i等于33时,由33/32及33%32知逻辑位33由a[1]的第1位表示(含第0位)。位运算中,[i>>5]即为a[1],1<<(i&0x1F)结果为2(即0000 0010),假如此时a[1]为0(即0000 0000),所以或运算的结果是将a[1]的第1位置1。
c语言实现代码如下:
#include<stdio.h>#include<stdlib.h>#include<time.h>#define N 10000000int a[N/32 + 1];//将逻辑上第i位置1void set(int i){ a[i>>5 ] = a[i>>5] | 1<<(i&0x1F);}//查看逻辑上第i位状态int test(int i){ return a[i>>5] & (1<<(i&0x1F));}//将逻辑上第i位置0void clear(int i){ a[i>>5] = a[i>>5] & (~(1<<(1&0x1F)));}//清零void pre(){ int i; for(i = 0; i< N; i++) clear(i);}int main(){ FILE *fp; srand((unsigned)time(NULL)); int count = 0; int t, i; if( (fp = fopen("input.txt", "r")) == NULL ) { printf("can not open the file!\n"); exit(0); } //对位图清零 pre(); //读入文件,将读入数据对应逻辑位置1 while(fscanf(fp, "%d", &t) != EOF){ set(t); } //输出排序结果 for(i = 0; i < N; i++) { if(test(i)){ printf("%d\n", i); } } fclose(fp); return 0;}
三、其他
在编程珠玑第一章的习题中,包括了将内存上限严格限制为1MB(习题5),因为上面的实现实际是需要1.25MB的。其实只要理解了前面的内容也还是很好实现的,最关键的两个思想是位图和多趟排序。以及习题6中将题目条件改为每个整数最多重复10次,则可以用4位来记录每个整数的出现次数(好吧 我开始的想法是用10位~)。
以上。
- 位图应用
- 位图法应用
- 位图算法的应用
- 位图法应用
- 位图排序及其应用
- 位图法的应用
- 第一章:位图的应用
- 【转】位图法应用
- 位图法应用
- 位图的应用
- 位图索引的应用
- 位图排序(位图技术应用)
- 位图的实现以及位图的应用
- 位图的实现以及应用
- day24之位图的实现和位图的应用
- 位图文件的另类应用:文件画图
- Flash 位图九宫格 -- 组件应用
- 海量数据---位图法的应用
- “Error setting expression 'id' with value '[Ljava.lang.String;@e41d4a'”解决办法!
- 安卓设计架构
- leetcode 80: Remove Duplicates from Sorted Array II
- nova.conf及其他配置
- 《数据库系统概念》学习笔记之二
- 位图应用
- Remove Nth Node From End of List
- jsp:跳转后页面css和js失效问题解决
- ui->setup(this); shortcut can't show
- Android studio新建工程时报错:Gradle DSL method not found: 'android()'问题解决
- 面试知识储备:新浪微博Android客户端的实现
- strlen和sizeof的区别
- 终端:Xcode升级失效解决办法
- poj 1258 Agri-Net(prim求最小生成树)