Если бы мне пришлось это кодировать, я бы, вероятно, сделал бы один проход, который разделил бы входные данные на множество выходных файлов в зависимости от первой пары символов или около того;цель состоит в том, чтобы сделать каждый выходной файл достаточно маленьким, чтобы поместиться в основную память.Затем я открыл бы каждый файл по порядку, отсортировал его в памяти и добавил к выводу.Первый проход - O (n), второй - более или менее O (n log n), и вы должны выполнить дисковый ввод-вывод четыре раза для каждой записи.Возможно, можно было бы добиться большего успеха с помощью какого-то загадочного алгоритма, но, вероятно, ненамного, и это легко понять и кодировать.
Если система ограничивает количество файлов, которые вы можете открыть одновременно, вы можете иметьразделить первый проход.Если строки распределены неправильно, некоторые промежуточные файлы могут быть слишком большими.
В псевдокоде:
open input file (r)
for i in ['aa', 'ab', 'ac', ..., 'zz']:
open output file[i] (w)
for record in input file:
write record to output file[record[0:2]]
close all files
open main output file (w)
for i in ['aa', 'ab', 'ac', ..., 'zz']:
open input file[i] (r)
slurp whole file into memory
close input file
sort data
append whole sorted file to main output file
РЕДАКТИРОВАТЬ: подождите, вы хотите сказать, что записи содержат только символы AB и C?Других писем нет?В этом случае вам, вероятно, придется разделить исходную подстроку длиннее 2. Разделение на первые 3 символа разделит ее на 27 файлов, каждый из которых имеет размер в среднем 370 МБ.