外部排序,用于处理大量按块可变长度的数据

时间:2019-07-14 01:05:56

标签: algorithm sorting block mergesort ram

我需要对分块可变长度数据应用某种排序算法。这里是约束:

  1. 数据长度不固定。

  2. 块大小是固定的。

  3. 一个块包含单个/多个数据。

  4. 考虑到我需要外部排序。 RAM无法容纳整个数据集。像数据集大小是20 GB。我最多可以使用2GB RAM。

示例: 为简单起见,请考虑每个元素都是块中以空格分隔的单词。

考虑块的大小为26(包括空格),第一个块包含5个元素,而第二个块仅包含3个元素。

由于块的大小固定,因此排序后的数据可能包含的块要多于已排序的块。

阻止:

[哈利·罗恩·德拉科·黑魔王] [赫敏·朗博顿·伏地魔]

排序块:

[黑暗德拉科·哈里·赫敏] [朗博顿·罗恩勋爵] [伏地魔]

在这种情况下,哪种算法/技术会更有效?

2 个答案:

答案 0 :(得分:1)

我的第一个倾向是:

编写一个脚本,该脚本读取输入文件,删除块并写入顺序文件。也就是说,获取包含以下内容的文件:

[Harry Ron Draco Dark Lord] [Hermione Longbottom Voldemort]

并写入此文件:

Harry
Ron
Draco
Dark
Lord
Hermione
Longbottom
Voldemort

然后,使用系统的sort实用程序(例如GNU sort)对文件进行排序,得到:

Dark
Draco
Harry
Hermione
Lord
Longbottom
Ron
Voldemort

然后,编写一个脚本,以读取该文件并构造这些块,然后将其写入最终输出。

就运行时间而言,这几乎可以肯定不是最有效的,但它简单,可靠,易于编码且易于证明正确。您可能可以对其进行编码,并在一两个小时内对其中的一部分数据进行测试。然后将其设置为适用于整个数据集。

答案 1 :(得分:1)

将进行外部合并排序。语句“已排序的数据可能包含比已排序的更多的块”表示数据记录不跨越块,因此,由于排序和合并过程中块中未使用的空间,所以块的数量可能会有所不同。第一遍将一组块读取到内存中,对数据记录进行排序,然后将经过排序的一系列块写入文件,重复此过程,直到处理完所有原始数据为止。其余遍将合并文件,直到生成单个排序的文件。 k合并可以用于此过程,最简单的是2合并。对于k> 2,最小堆将有助于查找k个运行中哪个具有“最小”的下一个元素。为了减少I / O开销,一次读写多个块。