Поиск наибольшей общей подстроки двух строк с использованием хеширования — различия между версиями
(→Время работы) |
(→Время работы) |
||
| Строка 23: | Строка 23: | ||
==Время работы== | ==Время работы== | ||
| − | Проведем оценку асимптотики времени работы предложенного алгоритма. Посмотрим сколько нам потребуется действий на каждом шаге бинарного поиска. Во-первых, хеширование подстрок строки <tex>s</tex> и запись их в Set требует <tex>O(|s|)</tex> шагов. Во-вторых, хеширование подстрок строки <tex>t</tex> и проверка их наличия в Set требует <tex>O(|t|)</tex> | + | Проведем оценку асимптотики времени работы предложенного алгоритма. Посмотрим сколько нам потребуется действий на каждом шаге бинарного поиска. Во-первых, хеширование подстрок строки <tex>s</tex> и запись их в Set требует <tex>O(|s|)</tex> шагов. Во-вторых, хеширование подстрок строки <tex>t</tex> и проверка их наличия в Set требует <tex>O(|t|)</tex>. Значит,на каждый шаг бинарного поиска требуется <tex>O(max(|s|, |t|))</tex> действий. Заметим, что всего для завершения бинарного поиска потребуется <tex>O(\log(\min(|s|, |t|)))</tex> шагов. Следовательно, суммарное время работы алгоритма будет <tex>O(\log(\min(|s|, |t|)) \times \max(|s|, |t|))</tex> действий. |
== Литература == | == Литература == | ||
Версия 13:07, 9 июня 2012
Постановка задачи
Имеются строки и такие, что элементы этих строк символы из конечного алфавита . Говорят, что строка является подстрокой строки , если существует такой индекс , что для любого справедливо . Требуется найти такую строку максимальной длины, что является и подстрокой , и подстрокой .
Алгоритм
Пусть длина наибольшей общей подстроки будет . Заметим, что у строк и обязательно найдется общая подстрока длины , так как в качестве такой строки можно взять префикс наибольшей общей подстроки. Рассмотрим функцию , которая для из области определения равна 1, если у строк и есть общая подстрока длины , иначе она равна 0. Согласно замечанию, функция должна по мере возрастания быть равной 1 до некоторого момента, а затем обращаться в 0. Собственно, максимальное значение, при котором функция принимает значение 1, является длиной наибольшей общей подстроки. Таким образом, требуется с помощью бинарного поиска найти это значение. В ходе работы придется проверять наличие общей подстроки заданной длины. При этом предполагается использовать хеширование, чтобы улучшить асимптотику алгоритма. Делается это следующим образом:
1) У строки хешируем подстроки заданной длины и полученные хеши записываем в Set.
2) У строки хешируем подстроки заданной длины и в случае совпадения хеша с элементом Set выполняем посимвольную проверку на совпадение подстрок.
Хеширование будем производить так же, как и в алгоритме Рабина-Карпа.
Псевдокод
findGCS(s, t)
n = min(|s|, |t|)
left = 0
right = n + 1
while (right - left > 1):
val = (left + right) / 2
if (f(val) == 1)
left = val
else
right = val
return left
Время работы
Проведем оценку асимптотики времени работы предложенного алгоритма. Посмотрим сколько нам потребуется действий на каждом шаге бинарного поиска. Во-первых, хеширование подстрок строки и запись их в Set требует шагов. Во-вторых, хеширование подстрок строки и проверка их наличия в Set требует . Значит,на каждый шаг бинарного поиска требуется действий. Заметим, что всего для завершения бинарного поиска потребуется шагов. Следовательно, суммарное время работы алгоритма будет действий.
Литература
- Кормен Т., Лейзерсон Ч., Ривест Р. Алгоритмы: построение и анализ. — 2-е изд. — М.: Издательский дом «Вильямс», 2007. — С. 1296.