给定一个填充了整数的非常大的文本文件,如何对其进行排序?

时间:2014-10-16 15:26:22

标签: algorithm sorting

我有一个非常大的文本文件(太大太容易在主记忆中一次)包含整数。我需要一个算法策略来排序吗?如果我计划实际执行此操作(使用Merge Sort行中的某些策略),它会失败还是操作系统可以处理它? 附:我不需要排序算法代码。

2 个答案:

答案 0 :(得分:0)

  1. 将文件拆分为可以处理的大小块。
  2. 对所有这些块进行排序。
  3. 打开其中两个已排序的块
    1. 创建输出文件
    2. 从每个文件中读取一行/值
    3. 确定较小的值。
    4. 将较小的值写入新文件
    5. 从包含较小值的文件中读取新值
    6. 如果一个文件达到EOF
      1. 将另一个的左侧内容复制到输出文件
      2. 关闭输出
      3. 删除两个块文件
      4. 如果剩余多个文件(包括您的输出)goto 3
  4. 示例:

    unsorted file:
    168971321965798321487954321687987321654654687987651316879 
    -> split
    16897132 19657983 214879543 21687987 321654654 6879876 51316879
    -> sort
    11236789 13567899 123445789 12677889 123445566 6677889 11356789
    ^        ^        -> 1
     ^       ^            1
      ^      ^             1
      ^       ^             2 
       ^      ^              3
        ^     ^               3
        ^      ^               5
        ^       ^               6
         ^      ^                6
         ^       ^                7
          ^      ^                 7
          ^       ^                 8
           ^      ^                  8
           ^       ^                  9
            eof    ^                   99
    -> merge 2 of them
    1112335667788999 11223445677788899 1234455666677889 11356789
    ->
    111112223334455666777778888899999 111233445556666677788899
    ->
    111111112222333334444555556666666677777777888888889999999
    

    正如用户2040251所述,这不是最佳方式,因为必须多次读取数字。更快的方法是并行打开所有块并比较选择minium值,因为文件只读取一次。

答案 1 :(得分:0)

Mooing Duck激发了我对另一种解决方案的评论:

使用一些类似地图的结构来映射value - &gt; count。 c ++ std::map<YourDataToSort, uint32_t>或某种ob平衡二叉树。

  1. 打开输入文件
  2. 明智地读取它/ line
    1. 如果元素已经在列表中:
      1. 增加点数
      2. 如果计数达到最大值且不能按照下述程序(2.2.2。)进行增加。
    2. 否则检查地图使用的内存(keyCount * sizeof(key) * sizeof(counter) + someOverhead*keyCount) - 您可以通过足够的容差设置一个由粗略猜测确定的关键限制:
      1. 如果未执行限制:
        • 添加一个计数为1的新条目
      2. 否则
        • 创建输出文件
        • 对映射结构的键进行排序(如果它们没有按实现排序)
        • 将每个键值count次写入输出
        • 关闭文件
        • 清晰的映射结构
        • 继续2。
  3. 与其他答案相比,此算法可能会产生更少的文件(显然取决于您的数据)。由于磁盘性能通常是瓶颈,因此映射结构处理是可接受的,因为它节省了一些昂贵的文件读取 - 合并 - 写入周期。如果生成多个文件,请将它们与另一个答案中描述的算法合并。

    与使用简单查找相比,此方法具有更高的内存要求,数字本身就是索引,但它可以处理负数,非常大的值范围,甚至不限于整数作为数据。唯一的要求是,data-&gt; count的映射是唯一的,不会产生冲突。