Я ищу подходящий алгоритм для сравнения двух файлов. Я думаю, что я могу сделать лучше, чем diff
из-за некоторых добавленных ограничений.
У меня есть два текстовых файла, каждый из которых содержит список файлов. Это снимки всех файлов в системе, сделанные в два разных раза. Я хочу выяснить, какие файлы были добавлены или удалены между двумя моментальными снимками.
Я мог бы использовать diff
для сравнения этих файлов, но я не хочу, потому что:
-
diff
пытается сгруппировать изменения вместе, обнаружив, какие фрагменты в файле изменились. Я ищу только список строк, которые изменились, и это должно быть гораздо более простой проблемой, чем поиск самой длинной-общей подпоследовательности или некоторой такой вещи. -
Обобщенные алгоритмы diff - это O (mn) во время выполнения или в пространстве. Я ищу нечто вроде O (m + n) во времени и O (1) в пространстве.
Вот ограничения на проблему:
-
Списки файлов находятся в одном порядке в обоих файлах. Они не обязательно в алфавитном порядке, но они находятся в одном и том же относительном порядке.
-
В большинстве случаев различий между списками не будет. Если есть различия, обычно будет только несколько новых/удаленных файлов.
-
Мне не нужно группировать результаты вместе, например, говоря "весь каталог удален" или "строки 100-200 являются новыми". Я могу индивидуально перечислить каждую строку, которая отличается.
Я думаю, что это эквивалентно проблеме наличия двух отсортированных списков и попытке выяснить различия между этими двумя списками. Сцепка - это элементы списка, которые не обязательно сортируются в алфавитном порядке, поэтому вы не знаете, является ли один элемент "большим", чем другой. Вы просто знаете, что файлы, которые присутствуют в обоих списках, будут в том же порядке.
Для чего это стоит, я ранее опубликовал этот вопрос на Спросить Metafilter несколько лет назад. Позвольте мне заранее ответить на несколько потенциальных ответов.
Ответ: Эта проблема называется Самая длинная общая подпоследовательность.
Ответ: Я пытаюсь избежать самой длинной общей подпоследовательности, потому что простые алгоритмы, выполняемые в O (mn) время/пространство, и лучшие из них сложны и более "эвристичны". Моя интуиция говорит мне, что существует алгоритм линейного времени из-за добавленных ограничений.
Ответ: Сортировка в алфавитном порядке, а затем сравнение.
Ответ: Это будет O (m log m + n log n), что хуже, чем O (m + n).