位圖排序

聲明

    本文問題取自<<編程珠璣>>.ios

概述

  1. 須要給一個磁盤文件排序編程

  2. 該文件最多包含n個正整數,每一個數都小於n且n = 10^7,而且該文件中不會有重複數據spa

  3. 按照升序排序code

  4. 磁盤空間充足,但內存只有1Morm

分析

    由於內存很小,因此最樸素的方式爲多趟排序,每次讀入一部分到內存進行排序。但分析後會發現最大的特色是沒有重複數據,若是使用1個bit位表明一個數據則1M最多可標記1024*1024*8的數字。所以用位圖排序在時間和空間上都很高效。排序

代碼

/**
 *  @brief file for 編程珠璣 chapter 1
 *  @note 讀取文件使用位圖排序
 */

#include <fstream>
#include <iostream>
#include <cstdio>
#include <cstdlib>

//#define DEBUG 
#define DBG(format, args...)						\
	   do { 												   \
		   printf("[ file: %-20s ,fun: %-20s , line: %-10d ] :"format, __FILE__, __func__, __LINE__, ##args);   \
	   } while (0)

namespace fileSort{
class bmpSort{
public:
        bmpSort(const unsigned int &valMax){
            bmpAlloc(valMax);
        }
        void bmpSet(const unsigned int val){
            if(val >= blen)
                return;
            bmp[val >> 5] |= 1 << (0x1f & val);
        }
        ~bmpSort(void) {
            bmpDestory();
        }
        friend std::ifstream& operator >> (std::ifstream&, bmpSort&);
        friend std::ofstream& operator << (std::ofstream&, bmpSort&);
private:
        void bmpAlloc(const unsigned int &len){
            unsigned int tlen = len < 0? 0 : len;
            arrayPosMax = (tlen >> 5) + (tlen & 0x1f ? 1 : 0);
            bitPosMax   = 33;
            bmp = new unsigned int[arrayPosMax];
            blen = len;
        }
        void bmpDestory(void){
            if(bmp)
                delete bmp;
        }
        void initSearch(void){
                arrayPos = 0;
                bitPos  = 0;
        }
        int nextVal(unsigned int &val){
            if(bitPos >= bitPosMax){
                    arrayPos++;
                    bitPos = 0;
            }
            if(arrayPos >= arrayPosMax)
                    return -1;
            if(0 == bmp[arrayPos])
                    bitPos = 0;
            while(0 == bmp[arrayPos] && arrayPos < arrayPosMax)
                    arrayPos++;
            if(arrayPos >= arrayPosMax)
                    return -1;
            while( 0 == (bmp[arrayPos] & (1 << bitPos)) ){
                    bitPos++;
            }
            if( bitPos >= bitPosMax)
                return -1;
            val = (arrayPos << 5) + bitPos;
            bmp[arrayPos] &= ~(1 << bitPos);
            bitPos++;
            return 0;
        }
        int arrayPos;
        int arrayPosMax;
        int bitPos;
        int bitPosMax;
        unsigned int * bmp;
        unsigned int blen;
};

std::ifstream& operator >> (std::ifstream& in, bmpSort& bs){
    int val;
    while(in >> val){
#ifdef DEBUG
        DBG("read %d\n", val);
#endif
        bs.bmpSet(val);
    }
    return in;
}

std::ofstream& operator << (std::ofstream& out, bmpSort& bs){
    unsigned int val;
    bs.initSearch();
    while( 0 == bs.nextVal(val)){
            out << val << "\n";
            if(out.fail())
                return out;
    }
    out << std::endl;
    return out;
}

};

using namespace std;
using namespace fileSort;

int main(int argc, char *argv[])
{
    unsigned int maxVal;
    if(4 != argc){
        DBG("error params\n");
        return -1;
    }
    ifstream in;
    ofstream out;

    maxVal = (unsigned int)atoll(argv[1]);

    in.open(argv[2], ios::in);
    if(in.fail()){
        DBG("open file for read fail\n");
        return -1;
    }
    out.open(argv[3], ios::out);
    if(out.fail()){
        DBG("open file for write fail\n");
        return -1;
    }
    bmpSort bs(maxVal);
    in >> bs;
    out << bs;
    return 0;
}
相關文章
相關標籤/搜索