积少成多

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

什么是位图?来自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;
    }

posted on 2016-06-01 14:52  x7b5g  阅读(578)  评论(0编辑  收藏  举报