下午好。
我遇到了一些问题。我可以解决它,但我对编程没有什么经验,在我看来,这个问题有更美观和合理的解决方案。
问题如下。给定一组总大小超过一百兆字节的文本文件。从2到N的文件数。文件包含已排序的唯一编号(例如,ID)。 它想要将所有数字合并到一个输出文件中。在结果文件中,还需要对数字进行排序。
我将按如下方式解决此问题: 打开所有文件。取出每个文件的第一个数字。将它们放入容器(例如矢量)中。找到容器中的最小数字。将最小数字放在输出文件中。在他的位置,从文件中输入以下数字,从中取最小数字。 似乎这个方法被称为"外部合并排序"。
请告诉我,有没有更聪明的方法来解决这个问题?
答案 0 :(得分:2)
为此确切问题创建了外部mergesort。这种复杂性是 N * log(number_of_files)。
为简单起见,您可以将文件流与数字一起存储在优先级队列中。
完全未经测试,但可能是有用的代码:
std::vector<ifstream> file_streams(stream_count);
// open streams.
using int_and_stream = std::pair<int, std::ifstream&>;
using cont = std::vector<int_and_stream>;
std::priority_queue<int_and_stream, cont, pair_comparer> queue;
for(auto& stream: file_streams){
int id;
stream >> id;
queue.push(std::make_pair(id, stream));
}
while(!queue.empty()){
auto smallest = queue.top();
outstream << smallest.first;
int id;
if(smallest.second >> id){ // file ended?
queue.push(std::make_pair(id, stream));
}
}
对于pair_comparer,您可以查看here
答案 1 :(得分:0)
你的方法很好。
但是你可以有一个数字/文件对的排序向量,这样你就可以花更少的时间找到最小的数字,因为在输入最小的数据后,你可以读取下一个值并使用更有效的算法将其插回到数组中,比线性排序。当您有大量输入文件时,这会更有效。
但是假设I / O的成本比数字比较昂贵得多,那么方法就可以了。
答案 2 :(得分:0)
更好的方法是将每个文件的当前头部存储在优先级队列中。然后在每个步骤中,您将获取优先级队列的顶部(注意此项目的输入文件),将其写入输出文件,然后将该输入文件的下一项推入优先级队列。