【问题标题】:Implementing External Merge Sort实现外部合并排序
【发布时间】:2013-02-27 20:13:30
【问题描述】:

我知道External merge sort 及其工作原理。 但目前我在实施它时遇到了困难。我已经编写了对数组进行排序和合并的代码,但是在从文件中读取数据和将数据写入文件时遇到了问题,我想在 C++ 中实现以下方法:

1. int * read(int s, int e) : This method should read from file all the number 
starting from 's' till 'e' and return the array
2. write(int a[], int s, int e) : This method should write to file the input 
array by replacing the numbers from s to e.

例如。

Given file has the following numbers:

1
2
3
4
5
6

read(0, 2) should return [1,2,3]
write([4,5,6], 0, 2) should update the file to :
4
5
6
4
5
6

如何实现这两种方法?

【问题讨论】:

    标签: c++ sorting file-io merge


    【解决方案1】:

    您应该做的第一件事是停止使用原始指针。

    std::vector<int> 将同样高效,而且更不容易出错。

    其次,文件格式很重要。我将假设一个包含 32 位有符号整数的二进制文件。

    现在读写的签名是:

    std::vector<int> read( std::ifstream const& f, int offset );
    void write( std::ofstream& f, int offset, std::vector<int> const& data );
    

    ifstreamofstream 有 seek 方法 -- 特别是,ifstreamseekgofstreamseekp

    ifstream.read( char* , length ) 在当前获取位置(由seekg 设置,由read 推进)从文件中读取length 字节。如果您不关心文件的内存布局,您可以从std::vector&lt;int&gt; 获取.data(),将其重新解释为char*,然后继续read( reinterpret_cast&lt;char*&gt;(vec.data()), sizeof(int)*vec.size() ) 一次读取缓冲区。

    ofstream 有一个类似的 write 方法,其工作方式大致相同。

    虽然将数据原始地写入磁盘并返回是危险的,但在大多数(每个?)实现中,在同一个执行会话(甚至可能在会话之间)写入和读取数据是安全的。如果数据是要在会话之间持续存在的,或者是代码的输出/输入,请多加注意。

    【讨论】:

      【解决方案2】:

      没有 C++ 标准函数可以跳转到文件中的行。因此,您必须逐行读取文件(例如使用 getline。http://www.cplusplus.com/reference/string/string/getline/)。

      据我所知,外部合并排序(旧的,专为具有几个磁带驱动器的计算机而设计)与单独的文件一起使用时,不需要像您这样的界面 - 您可以按顺序工作。

      【讨论】:

      • 正如 Yakk 提到的,可以使用 istream::seekg 和 istream::tellg 函数跳转到文本文件中的一行。但是,我不确定这些功能的时间复杂度和效率。请参阅以下链接中的示例:cplusplus.com/reference/istream/istream/seekg
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-11
      • 1970-01-01
      • 2014-07-15
      • 1970-01-01
      • 2018-12-01
      • 1970-01-01
      • 2021-09-03
      相关资源
      最近更新 更多