Было бы полезно иметь пример из нескольких строк и ожидаемого результата. Но из того, что я понимаю, вот некоторые идеи.
Вы определенно не хотите обрабатывать все файлы каждый раз, когда обрабатываете один файл или, что еще хуже, один 4-граммовый файл. В идеале вы должны просмотреть каждый файл один раз. Поэтому мое первое предложение состоит в том, чтобы вести промежуточный список частот (эти наборы из 10 точек данных), где они сначала учитывают только один файл. Затем, когда вы обработаете второй файл, вы обновите все частоты для элементов, с которыми вы сталкиваетесь (и предположительно добавите новые элементы). Тогда вы будете продолжать расти, увеличивая частоты по мере того, как вы найдете больше подходящих n-грамм. В конце напиши все.
Более конкретно, на каждой итерации я бы считывал новый входной файл в память как отображение строки в число, где строка - это, скажем, разделенный пробелом n-грамм, а число - это его частота. Затем я обработал бы промежуточный файл из последней итерации, который будет содержать ожидаемый результат (с неполными значениями), например «a b c d: 10 20 30 40 5 4 3 2 1 1» (вид предположения о результате, который вы ищете здесь). Для каждой строки я бы посмотрел на карте все подграммы на моей карте, обновил счет и записал обновленную строку в новый выходной файл. Этот будет использоваться в следующей итерации, пока я не обработаю все входные файлы.