什么是位图?来自http://www.cnblogs.com/dolphin0520/archive/2011/10/19/2217369.html
位图就是用一个bit来标记某个元素对应的值,键值就是该元素。最大的好处就是节省了内存空间。
可以利用位图进行排序,输入的数据是有要求的(数据不能重复,且大致直到数据的范围)。例如我们对{3,5,2,6,8}进行排序,我们可以利用一个
8bit的二进制向量set[1-8]来表示该集合,如果数据存在那么相应的set位就是1,否则就是0,那么最后我们的set={0,1,1,0,1,1,0,1}
这时候可以根据set集合输出对应的下标就是排序结果。
应用:
- 1,给40亿个不重复的unsinged int的整数,没有排过序,然后给出一个数,如果快速的判断这个数是否在那40亿个数中。
分析:因为unsigned int数据的最大范围在40亿左右,40*10^8/(1024*1024*8) = 476.837M,因此我们可以申请512M的内存空间,每个bit位表示一个unsigned int。然后读入40亿个数,
并设置相应的bit为1,然后读取要查询的数,查看bit是否为1?
- 2,给出40亿个unsigned int的整数,如何判断这40亿个数中哪些数是重复的?
我们也可以申请512M的内存空间,然后读取40亿个整数,并且将相应的bit位设置为1。如果是第一次读取某个数,那么相应的bit位为0;如果是第二次读取该数,那么相应的bit位为1;
============
c语言中没有bit这个概念,因此我们必须通过位操作来实现。
假设有若干不重复的数据,数据的范围是[1-100],就是MAX<=100,MIN>=1,因为我们可以申请一个int a[100/(4*8)+1] = int a[4];
怎么利用c语言实现位图?os内存管理中给出了答案。
假设由数据32,那么应该将逻辑下标为32的二进制设置1,这个逻辑位置有两部分组成: 字节位置(数组下标),位位置
字节位置=数据/32;位运算就是data>>5右移5位
位位置=数据%32,就是data&0x1f(利用位运算求余数问题)
==========
下面的例子就是对1-9999的数字排序。
#define MAX 100 #define SHIFT 5 #define MASK 0x1f #define DIGITS 32 #define NUMs 10000 class A{ public:///sort 1000000 by decs int data[NUMs]; int tmp[NUMs/32+1]; void init(){ memset(data,0,sizeof(data)); for(int i = 0;i<NUMs;i++){ data[i] = NUMs-i; } } /// void show(){ for(int i = 0;i<NUMs;i++){ cout<<data[i]<<" "; if((i%10)==0) cout<<endl; } } /// void sort(){ for(int i = 0;i<NUMs;i++){ set(data[i]); } } void show_solution(){ for(int i = 0;i<NUMs;i++){ if(test(i)) cout<<i<<" "; if(i%10==0) cout<<endl; } } ///set void set(int n){ tmp[n>>SHIFT] = tmp[n>>SHIFT]|(1<<(n&MASK)); } ///clear void clear(int n){ tmp[n>>SHIFT] = tmp[n>>SHIFT]&~(1<<(n&MASK)); } ///test int test(int n){ return tmp[n>>SHIFT] & (1<<(n&MASK)); } void test(){ cout<<"begining"<<endl; init(); show(); sort(); show_solution(); cout<<"end"<<endl; } };
===========
利用c++中的bitset类型实现?
using namespace std; #define MAX 100 #define SHIFT 5 #define MASK 0x1f #define DIGITS 32 #define NUMs 10000 class A{ public:///sort 1000000 by decs int data[NUMs]; int tmp[NUMs/32+1]; void init(){ memset(data,0,sizeof(data)); for(int i = 0;i<NUMs;i++){ data[i] = NUMs-i; } }
void test(){ cout<<"begining"<<endl; bitset<NUMs+1> b; init(); for(int i = 0;i<NUMs;i++){ b.set(data[i],1); } for(int i = 0;i<NUMs;i++){ if(b[i]==1) cout<<i<<" "; if(i%10==0) cout<<endl; } cout<<"end"<<endl; } };
void test(){
cout<<"begining"<<endl;
cout<<"int-"<<sizeof(int)<<endl;//4
cout<<"bool-"<<sizeof(bool)<<endl;//1
cout<<"char-"<<sizeof(char)<<endl;//1
cout<<"double-"<<sizeof(double)<<endl;//8
cout<<"float-"<<sizeof(float)<<endl;//4
cout<<"long-"<<sizeof(long)<<endl;//8
cout<<"long long-"<<sizeof(long long)<<endl;//8
cout<<"end"<<endl;
}