Для этой проблемы можно использовать суффиксные массивы . Они содержат начальные позиции каждого суффикса строки, отсортированного в лексикографическом порядке. Даже если они могут быть построены наивно в сложности , существуют методы, чтобы построить их в сложности Θ ( n ) . Смотрите, например, это и это . Давайте назовем этот суффиксный массив SA.O ( n logн )Θ ( н )
После создания массива суффиксов нам необходимо создать массив Longest Common Prefix (LCP) для массива суффиксов. Массив LCP хранит длину самого длинного общего префикса между двумя последовательными префиксами в массиве суффиксов (лексикографические последовательные суффиксы). Таким образом, LCP [i] содержит длину самого длинного общего префикса между SA [i] и SA [i + 1]. Этот массив также может быть построен за линейное время: см. Здесь , здесь и здесь для некоторых хороших ссылок.
Теперь, чтобы вычислить длину самого длинного префикса, общего для любых двух суффиксов в дереве суффиксов (вместо последовательных суффиксов), нам нужно использовать некоторую структуру данных RMQ . В приведенных выше ссылках было показано (и это легко увидеть, если массив визуализировать как дерево суффиксов), что длина самого длинного общего префикса между двумя суффиксами, имеющими позиции и v ( u < v ) в массиве суффиксов , может быть получено как m i n u < = k < = v - 1 L C P [ k ]Uvты < vм я нu < = k < = v - 1L Cп[ к ], Хороший RMQ может предварительно обработать массив за O ( n ) или O ( n log n ) и ответить на запросы вида L C P [ u , v ] за O ( 1 ) . Смотрите здесь для краткого алгоритма RMQ, и здесь для хорошего учебника по RMQ и отношениям (и сокращениям) между LCA и RMQ. Это еще один хороший альтернативный подход.L CпO ( n )O ( n logн )L Cп[ u , v ]O ( 1 )
С помощью этой информации мы создаем массив суффиксов и связанные с ними массивы (как описано выше) для объединения двух строк с разделителем между ними (например, T # P, где «#» не встречается ни в одной из строк). Затем мы можем выполнить k несоответствие строк, используя метод "кенгуру". Это и это объясняет метод кенгуру в контексте деревьев суффиксов, но может быть непосредственно применен и к массивам суффиксов. Для каждого индекса текста T найдите L C P суффикса T, начинающегося с i, и суффикса PiTLCPTiPначиная с 0. Это дает местоположение, после которого возникает первое несоответствие при сопоставлении с T [ i ] . Пусть эта длина будет l 0 . Пропустите несовпадающий символ в T и P и попробуйте сопоставить оставшиеся строки. То есть снова найдите L C P из T [ i + l 0 + 1 ] и P [ l 0 + 1 ] . Повторяйте это, пока не получите k несоответствий или не завершится строка. каждыйPT[i]l0TPLCPT[i+l0+1]P[l0+1]k является O ( 1 ) . Есть O ( K ) L С Р «S для каждого индекса я из T , давая это общая сложность O ( п к ) .LCPO(1)O(k) LCPiTO(nk)
O(nk+(n+m)log(n+m))O(nk+nlogn)m=O(n)O(nk)