Удалите дубликаты из двух больших текстовых файлов, используя unordered_map - PullRequest
2 голосов
/ 13 июня 2011

Я новичок во многих из этих библиотек C ++, поэтому, пожалуйста, прости меня, если мои вопросы кажутся наивными.

У меня есть два больших текстовых файла, около 160 МБ каждый (около 700000 строк каждая).Мне нужно удалить из file2 все дубликаты строк, которые появляются в file1.Для этого я решил использовать unordered_map с 32-символьной строкой в ​​качестве ключа.Строка из 32 символов - это первые 32 символа в каждой строке (этого достаточно, чтобы однозначно идентифицировать строку).

В любом случае, поэтому я в основном просто иду через первый файл и помещаю подстроку из 32 символов каждой строки внеупорядоченная карта.Затем я просматриваю второй файл и проверяю, существует ли строка в file2 в моем unordered_map.Если он не существует, я записываю полную строку в новый текстовый файл.

Это прекрасно работает для файлов меньшего размера ... (по 40 МБ каждый), но для этих файлов 160 МБ ... требуетсяочень долго вставлять в хеш-таблицу (прежде чем я даже начну смотреть на file2).Около 260 000 вставок .. кажется, что оно остановилось или идет очень медленно.Возможно ли, что я достиг своих ограничений памяти?Если так, кто-нибудь может объяснить, как рассчитать это?Если нет, могу ли я сделать что-то еще, чтобы сделать это быстрее?Может быть, выбрать пользовательскую хеш-функцию или указать некоторые параметры, которые помогут ее оптимизировать?

Моя пара ключевых объектов в хеш-таблице имеет вид (string, int), где длина строки всегда составляет 32 символа, а int - этоколичество я использую для обработки дубликатов.Я использую 64-битную ОС Windows 7 с 12 ГБ ОЗУ.

Любая помощь будет принята с благодарностью .. спасибо, ребята !!

Ответы [ 2 ]

3 голосов
/ 13 июня 2011

Вам не нужна карта, потому что у вас нет ассоциативных данных.Неупорядоченный набор сделает работу.Кроме того, я бы пошел с некоторой реализацией эффективного хэш-набора памяти, как Google sparse_hash_set .Это очень эффективно использует память и может хранить содержимое на диске.

Кроме того, вы можете работать с небольшими порциями данных.Например, разбейте ваши файлы на 10 блоков, удалите дубликаты из каждого, затем объедините их, пока не дойдете до одного блока без дубликатов.Вы поняли.

0 голосов
/ 13 июня 2011

Я бы не писал для этого программу на C ++, а использовал бы некоторые существующие утилиты. В Linux, Unix и Cygwin выполните следующее:

cat два файла в один большой файл:

# cat file1 file2 > file3

Используйте sort -u для извлечения уникальных строк:

# sort -u file3 > file4

Предпочитают использовать утилиты операционной системы, а не (переписывать) свои.

...