Иногда способ обнаружить, что две сложные вещи «равны», состоит в том, чтобы сделать какой-нибудь дешевый тест, который верен, если они равны, и редко верен, если это не так.Те, кто проходит этот уличный тест, затем проверяются более тщательно ... но редко, поэтому тест на полное равенство может быть дорогим и при этом не запускаться при каждом сравнении.
Что бы я сделал в этом случае, это взять всефайлы и сортировать их строки.(Возможно, вы захотите подавить пустые строки, если вы ищете соответствующий текст, и лишить линии конечных пробелов, но это ваш выбор).Вероятно, полезно удалить дубликаты строк.
Теперь сравните каждый файл со всеми более длинными файлами, чтобы увидеть, является ли он префиксом.(Не может быть префиксом, если другой файл короче, поэтому мы избавляемся от 1/2 сравнения только на основе размеров).Если отсортированный файл A является префиксом отсортированного файла B, то вы можете выполнить более сложный тест, чтобы увидеть, вставлен ли настоящий файл A в файл B (что, как я подозреваю, будет с большой вероятностью истинным, если отсортированные файлы пройдут тест префикса).).
Имея эту идею, теперь мы можем ее оптимизировать.Вместо того, чтобы хранить строки текста, мы берем каждый файл и хэшируем каждую строку, давая файл хеш-кодов.Сортируй это.Выполните оставшуюся часть процедуры.
Следующий прием: решите, что наши хеш-коды имеют размер 8 или 16 бит.Это позволяет им соответствовать характеру вашего любимого языка программирования.Теперь ваш тест сравнения префиксов может состоять из сбора хеш-кодов размером в символ для каждого файла и сравнения строк более коротких и более длинных.На данный момент мы переместили проблему с чтения диска на эффективное сравнение в памяти;мы, вероятно, не сможем ускорить его, потому что чтение с диска очень дорого по сравнению с вычислениями в памяти.