Эффективный способ памяти удалять повторяющиеся строки в текстовом файле с использованием С++
Каков наиболее эффективный способ удаления дубликатов строк в большом текстовом файле с помощью С++?
Позвольте пояснить, я не прошу код, просто лучший метод. Дублированные строки не гарантированно смежны. Я понимаю, что подход, оптимизированный для минимального использования памяти, приведет к более медленным скоростям, но это мое ограничение, так как файлы слишком велики.
Ответы
Ответ 1
i будет хэш каждой строки, а затем искать обратно к строкам, которые имеют не-уникальные хэши и сравнивать их по отдельности (или буферизованным образом). это будет хорошо работать с файлами с относительно низким количеством дубликатов.
Когда вы используете хеш, вы можете установить память, используемую для постоянной суммы (т.е. у вас может быть крошечная хеш-таблица с 256 слотами или чем-то большим. В любом случае количество mem может быть ограничено любым постоянная сумма.) значения в таблице представляют собой смещение строк с этим хешем. поэтому вам нужен только line_count * sizeof (int) плюс константа для поддержки хеш-таблицы.
еще проще (но гораздо медленнее) было бы сканирование всего файла для каждой строки. но я предпочитаю первый вариант. это наиболее эффективный вариант памяти. вам нужно будет только сохранить 2 смещения и 2 байта для сравнения.
Ответ 2
Чтобы свести к минимуму использование памяти:
Если у вас неограниченный (или очень быстрый) дисковый ввод-вывод, вы можете написать каждую строку в свой собственный файл с именем файла, являющимся хешем + некоторым идентификатором, указывающим порядок (или без ордера, если заказ не имеет значения). Таким образом, вы используете файловую систему как расширенную память. Это должно быть намного быстрее, чем повторное сканирование всего файла для каждой строки.
В дополнение к тому, что сказано ниже, если вы ожидаете высокую повторяемость, вы можете сохранить некоторый порог хэшей как в памяти, так и в файле. Это даст гораздо лучшие результаты для высоких уровней дублирования. Поскольку файл настолько велик, я сомневаюсь, что n^2
является приемлемым во время обработки. Мое решение O(n)
в скорости обработки и O(1)
в памяти. Это O(n)
в требуемом дисководе, используемом во время выполнения, однако другие решения не имеют.
Похоже, что вы можете работать на ограниченном аппаратном обеспечении с различными спецификациями, поэтому вам нужно протестировать несколько алгоритмов удаления и дублирования, прежде чем вы решите, что лучше для долгосрочной реализации.
Ответ 3
Вы можете использовать эффективную сортировку ввода-вывода (например, команду сортировки unix), а затем прочитать файл в строке за строкой, сравнивая каждую строку с ранее прочитанной. Если эти два равны, ничего не выводить, если они не выводят строку.
Таким образом, объем памяти, используемой алгоритмом, является постоянным.
Ответ 4
Простое решение грубой силы (очень небольшое потребление памяти):
Пропустите n ^ 2, пройдите через файл и удалите повторяющиеся строки. Скорость: O (n ^ 2), Память: постоянная
Быстрое (но плохое, потребление памяти):
Решение Stefan Kendall: хешировать каждую строку, хранить их на какой-либо карте и удалять линию, которая уже существует. Скорость: O (n), память: O (n)
Если вы готовы пожертвовать файловым порядком (я предполагаю, что нет, но я добавлю его):
Вы можете отсортировать строки, а затем выполнить удаление дубликатов. скорость: O (n * log (n)), Память: постоянная
изменить:
Если вам не нравится идея сортировки содержимого файла или попытки сохранить уникальные хэши, но могут обрабатывать использование памяти O (n): вы можете идентифицировать каждую строку с помощью 32-разрядного или 64-битного позиционного маркера (в зависимости от размера файла) и сортировки позиции файла вместо содержимого файла.
edit # 2: caveat: строки сортировки в памяти различной длины сложнее, чем сказать, массив ints... на самом деле, думая о том, как память должна сдвигаться и перемещаться на этапе слияния, Я второй догадываюсь о моей способности сортировать файл, подобный этому в n * log (n)
Ответ 5
Почему бы просто не обратиться к Knuth, Sorting and Search? Это даст вам большой опыт для принятия сбалансированного решения.