Изменения

Перейти к: навигация, поиск
Псевдокод
}}
{{Определение
|definition = Будем говорить, что строка <tex>z[0 \,\mathinner{\ldotp\ldotp}ldots \, m-1]</tex> является подстрокой строки <tex>s[0 \,\mathinner{\ldotp\ldotp}ldots \, n-1]</tex>, если существует такой индекс <tex>k \in [0\, \mathinner{\ldotp\ldotp}ldots \, n - m]</tex>, что для любого <tex>i \in [0 \,\mathinner{\ldotp\ldotp}ldots \, m-1]</tex> справедливо <tex>s[k + i] = z[i]</tex>.
}}
== Алгоритм ==
Пусть длина наибольшей общей подстроки будет <tex>x</tex>. Заметим, что у строк <tex>s</tex> и <tex>t</tex> обязательно найдется общая подстрока длины <tex>y \in [0 \mathinner{\ldotp\ldotp} ldots x]</tex>, так как в качестве такой строки можно взять префикс наибольшей общей подстроки. Рассмотрим предикат <tex>f \colon [0 \mathinner{\ldotp\ldotp} ldots \min(|s|, |t|)] \rightarrow \{0, 1\}</tex>, который для <tex>i</tex> из области определения истинен, если у строк <tex>s</tex> и <tex>t</tex> есть общая подстрока длины <tex>i</tex>, иначе ложен. Согласно замечанию, предикат <tex>f</tex> должен по мере возрастания <tex>i</tex> быть истинным до некоторого момента, а затем обращаться в ложь. Собственно, максимальное значение, при котором предикат истинен, является длиной наибольшей общей подстроки. Таким образом, требуется с помощью [[Целочисленный двоичный поиск|двоичного поиска]] найти это значение. В ходе работы придется проверять наличие общей подстроки заданной длины. Для этого будем использовать хеширование, чтобы улучшить асимптотику алгоритма. Алгоритм является эвристическим и может выдавать неверный ответ, так как совпадение хешей строк не гарантирует равенство строк. Поэтому нужно выполнить проверку нескольких случайных символов подстрок на совпадение, проиграв при этом по времени работы. Алгоритм работает следующим образом:
* у строки <tex>s</tex> хешируем подстроки заданной длины и полученные хеши записываем в Set,
hashes = хеши подстрок строки <tex>s</tex> длины <tex>i</tex>
'''for''' j = 0 '''to''' |t| − i
hash = hash(t[j ... j + i − 1])
'''if''' hash '''in''' hashes
'''if''' совпали несколько случайных символов подстрок
442
правки

Навигация