• 如何给10^7个数据量的磁盘文件排序--bitset


    题目:

    输入:给定一个文件,里面最多含有n个不重复的正整数(也就是说可能含有少于n个不重复正整数),且其中每个数都小于等于n,n=10^7。
    输出:得到按从小到大升序排列的包含所有输入的整数的列表。
    分析:

        1、归并排序。你可能会想到把磁盘文件进行归并排序,但题目要求你只有1MB的内存空间可用,所以,归并排序这个方法不行。
        2、位图方案。熟悉位图的朋友可能会想到用位图来表示这个文件集合。例如正如编程珠玑一书上所述,用一个20位长的字符串来表示一个所有元素都小于20的简单的非负整数集合,边框用如下字符串来表示集合{1,2,3,5,8,13}:

    0 1 1 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0

    上述集合中各数对应的位置则置1,没有对应的数的位置则置0。

        说明:使用bitset方法必须满足的条件是:不能有重复的数字

     
    #include <assert.h>
    #include <bitset>
    #include <iostream>
    using namespace std;
    const int maxEachScan = 5000000;
    const int maxSortNumber = 10000000;
    
    void SortBigNumber()
    {
        FILE *fp_unSortFile = fopen("d:\unSort_data.txt","r+");
        FILE *fp_SortFile = fopen("d:\sort_data.txt", "w+");
        assert(fp_unSortFile);
        bitset<maxEachScan> bit_map;        //因为数据比较大,分成两次执行,这里相当于定义了一个数组来保存所有结果
        bit_map.reset();                                   //置0
        int num;
    
        /*第一遍遍历*/
        while (fscanf(fp_unSortFile,"%d",&num)!=EOF)
        {
            if (num < maxEachScan)
                bit_map.set(num, 1);                //bitset内部机制,保存在bit_map中
        }
        
        for (int i = 0; i < maxEachScan; i++)   //遍历bit_map
        {
            if (bit_map[i] == 1)
                fprintf(fp_SortFile, "%d", i);      //这里就是将数据用bit保存(放在bitmap中),再输出的时候输出其对应的数字    
        }
    
        /*第二遍遍历*/
        bit_map.reset();
        fseek(fp_unSortFile,0,SEEK_SET);  //移到文本的开头
        while (fscanf(fp_unSortFile,"%d",&num)!=EOF)
        {
            if (num >= maxEachScan&&num < maxSortNumber)
                bit_map.set(num-maxEachScan, 1); 
        }
    
        for (int i = 0; i < maxEachScan; i++)
        {
            if (bit_map[i] == 1)
                fscanf(fp_SortFile,"%d",i+maxEachScan);
        }
    
        fclose(fp_unSortFile);
        fclose(fp_SortFile);
    }
    需要用到的函数:
    1.fseek: 用来将指针移到指定位置,本代码主要是移动到文本开头,进行第二次扫描
    2.bitset 容器
      bitset:: reset   用来将bit位全部置0
     
      bitset:: set  给bit位置设置0或者1 来表示这个bit有没有元素
    // bitset::set
    #include<iostream>// std::cout
    #include<bitset>// std::bitset
    int main ()
    {
    std::bitset<4> foo;
    std::cout << foo.set()<<'
    ';// 1111
    std::cout << foo.set(2,0)<<'
    ';// 1011
    std::cout << foo.set(2)<<'
    ';// 1111
    return0;
    }
    Edit&Run
    Output:
    1111
    1011
    1111
    3.文件的读取
     
    fscanf(fp_unSortFile,"%d",&num)!=EOF %d可以限定我们读取的是int类型EOF判断文件尾部
     
     参考:http://blog.csdn.net/v_JULY_v/article/details/6451990
  • 相关阅读:
    JavaScript二进制数据序列化和反序列化
    三维变换矩阵推导笔记
    如何制作一款“有毒”的游戏
    如何使用visual studio将你的程序打包成安装包
    游戏设计模式系列(三)—— 策划变心太快?也许可以使用组合
    使用LayaAir解析xml文件
    游戏设计模式系列(二)—— 适时使用观察者模式,解耦你的代码
    游戏设计模式系列(一)—— 单线逻辑&&数据驱动,搞定最容易卡死的结算界面
    vs2010 win32程序中 sqlserver 2008 express的简单使用 (C++)
    UVALive 6529
  • 原文地址:https://www.cnblogs.com/menghuizuotian/p/3840047.html
Copyright © 2020-2023  润新知