您的位置:首页 > 编程语言 > C语言/C++

位图 c++ 位图排序

2016-06-01 14:52 429 查看
什么是位图?来自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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: