zoukankan      html  css  js  c++  java
  • 如何给磁盘文件排序?--学习《编程珠玑》

    输入:一个最多包含n个正整数的文件,每个都小于n,其中n=10^7。如果在输入文件中有任何证书重复出现就是致命错误。没有任何其他数据与该整数相关联。

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

    约束:最多有(大约)1MB的内存空间可用,有充足的磁盘空间可用。运行时间最多几分钟,运行时间为10秒就不需要进一步优化了。

    程序设计:

    1)基于磁盘的归并排序:多次读写,多次归并排序。每读入输入文件一次,进行归并排序,再写入输出文件一次。

    工作文件多次读写。

    2) 多趟快速排序:1M内存可以保存250, 000个整数,遍历输入文件40次:第一次将0~249, 999之间的整数读入内存,进行快速排序(内存中快速排序最快),写入输出文件;第二次将250,000~499, 999之间的整数读入内存,进行快速排序,写入输出文件;以此类推,到第40趟遍历时,将975, 000~999, 999之间的整数进行快速排序,写入输出文件,整个排序过程完成。

    读入输入文件多次,写输出文件仅一次,不使用中间文件。优于1)。

    3)神奇排序:读输入文件仅一次,且不使用中间文件。==> 能否用大约800万个可用位来表示最多1000万个互异的整数。

    使用位图或维向量表示集合。使用一个具有1000万个位的字符串来表示这个文件,其中,当且仅当整数i在文件中存在时,第i位为1。(有200万个稀疏位?)

    使用这种算法的限制:

    1. 输入数据限制在相对较小的范围内;
    2. 数据没有重复;
    3. 每条记录可用整数来表示

     代码:

    /**
    * 使用比特向量对n个不重复的整数排序, n = 10^7
    */
    #include <stdio.h>
    #include <stdlib.h>
    
    #define BITSPERWORD 32
    #define SHITF 5
    #define MASK 0X1F
    #define N 10000000
    
    int a[1 + N / BITSPERWORD];
    int x[N];
    
    void set(int i) {
        a[i >> SHITF] |= (1 << (i & MASK));
    }
    
    void clr(int i) {
        a[i >> SHITF] &= !(1 << (i & MASK));
    }
    
    int test(int i) {
        return a[i >> SHITF] & (1 << (i & MASK));
    }
    
    void initialize(int k) {
        for (int i = 0; i < N; i++)
            x[i] = i;
        int tmp;
        int swapId;
        for (int i = 0; i < k; i++)
        {
            tmp = x[i];
            swapId = rand() + i + 1;
            x[i] = x[swapId];
            x[swapId] = tmp;
        }
    }
    
    int main(void) {
        int i;
        for (i = 0; i < N; i++)
            clr(i);
        //while (scanf_s("%d", &i) != EOF)
        initialize(100);
        for (i = 0; i < 100; i++)
            set(x[i]);
        for (i = 0; i < N; i++)
            if (test(i))
                printf("%d
    ", i);
    
        return 0;
    }

    :) 对小问题的仔细分析有时可以得到明显的实际益处。

    千里之行,始于足下~
  • 相关阅读:
    HDU
    UVa——540Team Queue(STL练习map、queue数组的综合使用)
    NOJ——1659求值(log10取对数+floor取整数部分+可有可无的快速幂)
    NOJ——1658平方和(自然数平方和公式和取模法则)
    HDU——2723Electronic Document Security(STL map嵌套set做法)
    HDU——1982Kaitou Kid
    HDU——1073Online Judge(string类以及其对应函数)
    HDU——1062Text Reverse(水题string::find系列+reverse)
    HDU——1009FatMouse' Trade(贪心+结构体+排序)
    HDU——1799循环多少次(杨辉三角/动态规划/C(m,n)组合数)
  • 原文地址:https://www.cnblogs.com/wm123/p/5294064.html
Copyright © 2011-2022 走看看