bitmap 转byte[]后读取_C++ BitMap 排序

44de809a55973dbd126fa074cc7d1b17.png

一、问题描述

输入:一个最多包含n个正整数的文件,每个数都小于n,其中

并且每个数都不相同。

输出:按生序排序的输入整数的列表。

约束: 1MB的内存空间可用,运算时间10s以内。

二、解决方案

因为每一个数都不相同,我们可以构造一个 N 个比特位的序列,N位这些整数中的最大值,然后将这1 000 0000 个数一一映射到该比特序列中,最后遍历该比特序列的映射关系,就可以得到排序后的序列。

我们来看一个简单的例子

427ff3a6e1243d3e1d85978972d0345f.png


图1-简单排序例子

三、工程实现

在本文中,我们采用C++来实现该算法。我们将这1000 0000 个数存储在一个整形数组中,为了利用好每个比特位,需要用到或和异或的比特为操作,下面是我实现的BitMap的类。

class BitMap{

public:
BitMap(){
    this->arr = new int[REQUIRED_SIZE];
}
~BitMap(){
    delete[] this->arr;
}
void set(int index){
    int bucket = index / RADIX;
    int value = this->arr[bucket];
    this->arr[bucket] |= (1 << ((index % RADIX) - 1));
}
bool get(int index){
    int bucket = index / RADIX;
    int value = this->arr[bucket];
    return (((value & (1 << ((index % RADIX) - 1))) ^ (1 << ((index % RADIX) - 1))) == 0);
}
private:
    int*  arr;
    const int REQUIRED_SIZE = 312500;
    const int RADIX = 32;
};

实现中关键的操作就是

   this->arr[bucket] |= (1 << ((index % RADIX) - 1)); // 设置位
   return (((value & (1 << ((index % RADIX) - 1))) ^ (1 << ((index % RADIX) - 1))) == 0); //读取位

为了方便理解,还是画个图来解释一下

741f62fa70b2f924ef629247dc108a58.png


2.C++实现详细图解

然后就是利用BitMap去排序了,这个比较简单,将值一个个写入到bitmap,然后遍历bitmap,记录index序列就行了,下面是对应的实现。

class Sort{

public:
    Sort(){ bt =new BitMap(); }
    ~Sort(){delete bt; }
    void sort(std::vector<int> &arr){
    for(std::vector<int>::iterator it = arr.begin(); it != arr.end(); it++){
            bt->set(*it);
    }
    int ctr = 0;
    for(int i = 1; i < MAX_INT; i++){
             if(bt->get(i)){
                    arr[ctr++] = i;
             }
        }
    }
private:
    const int MAX_INT = 10000000;
    BitMap *bt;
};

详细代码见GitHub (https://github.com/vajn/LINUX_DEMO/blob/master/BitMapSort/btsort.cc)

参考

编程珠玑 第2版

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值