У меня возникла необычная задача, и до сих пор я не могу определить наиболее эффективный алгоритм для атаки этого.
Учитывая следующие две строки в качестве примера, найдите все общераспространенные подстроки между двумя строками любой длины и подсчитайте количество вхождений всех этих общих подстрок в строке 2. Ваш алгоритм также должен быть способный вычислять общие подстроки между файлами, содержащими строки размером до 100 МБ или более.
Пример:
Строка 1: ABCDE512ABC361EG51D
Строка 2: ADE5AHDW4131EG1DG5C
Учитывая эти 2 строки, этот алгоритм найдет следующие общие подстроки: А, С, D, Е, 5,1,3, G, DE, Е5, EG, G5,1D, DE5,1EG
И затем из этих общих разделяемых подстрок мы найдем, сколько из них имеет место в строке 2.
A: 2 вхождения в строку 2
C: 1 в строке 2
D: 3 вхождения в строку 2
и т.д..
Первый подход, который я использовал для обертывания вокруг этой проблемы, был грубым, заставляя мой путь через вычисление общих общих подстрок с использованием 2 вложенных циклов - очевидно, наименее эффективным, но это был быстрый и грязный способ получить представление о том, что ожидаемые выходы должны быть с меньшим тестовым входом и самым медленным временем для запуска, что составляло около 2 минут, чтобы вычислить все общие общие подстроки между двумя файлами, содержащими строки ascii размером 50 КБ. Увеличение размера до 1mb привело к тому, что это привело к остановке виз из-за большого количества полных вложенных итераций, которые должны были произойти, чтобы вычислить это.
В следующем подходе использовались деревья - видя, сколько памяти я могу обменять, чтобы оптимизировать время вычисления. Этот подход был намного быстрее. Те же два файла размером 50 КБ, которые заняли 2 минуты с помощью метода грубой силы, были почти мгновенными. Работа с файлами размером 1 МБ была очень быстрой (секунда), но по мере того, как я продолжал тестировать с большими и большими размерами файлов, я быстро начал сталкиваться с проблемами памяти из-за размеров деревьев.
Примечание. Строковые файлы будут содержать только символы ASCII!
Изменить:
Я немного увеличиваю это, пожалуйста, см.
https://gist.github.com/braydo25/f7a9ce7ce7ad7c5fb11ec511887789bc