zoukankan      html  css  js  c++  java
  • 位图 c++ 位图排序

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

  • 相关阅读:
    IsPostBack
    判断客户端.net版本
    js 汉字转换成拼音 转载
    观察者模式
    常用的js阻止冒泡的方法
    jquery中事件的绑定
    uclinux编译 skyeye运行
    dotNet学习之路 Struct与Class异同点
    dotNet学习之路 Delegate内部原理
    设计模式之旅(策略模式) 十号刚发工资的博友们,赶紧跟我一起算算你们的老板有没有给你少发工资。。。
  • 原文地址:https://www.cnblogs.com/li-daphne/p/5549600.html
Copyright © 2011-2022 走看看