Участница:Mariashka — различия между версиями
Mariashka (обсуждение | вклад) |
Mariashka (обсуждение | вклад) |
||
Строка 49: | Строка 49: | ||
# Предподсчитаем следующие массивы с помощью z-функции: | # Предподсчитаем следующие массивы с помощью z-функции: | ||
− | ## <tex> LP[i] = lcp(u[i..u.len], | + | ## <tex> LP[i] = lcp(u[i..u.len], v) </tex>, где <tex> lcp </tex> {{---}} наибольший общий префикс |
## <tex> LS[i] = lcs(u[1..i], u) </tex>, где <tex> lcs </tex> {{---}} наибольший общий суффикс | ## <tex> LS[i] = lcs(u[1..i], u) </tex>, где <tex> lcs </tex> {{---}} наибольший общий суффикс | ||
# Переберем длину повтора <tex> 2p </tex>. Для каждого <tex> p </tex> получим интервал индексов конца повтора в строке <tex> v </tex>: <tex> [x, y] </tex>. | # Переберем длину повтора <tex> 2p </tex>. Для каждого <tex> p </tex> получим интервал индексов конца повтора в строке <tex> v </tex>: <tex> [x, y] </tex>. |
Версия 20:41, 28 апреля 2015
Определение: |
Повтором (англ. repeatition) называется непустая строка вида |
Алгоритм Мейна-Лоренца (англ. Main-Lorentz algorithm) — алгоритм на строках, позволяющий найти все повторы в строке
заАлгоритм
Данный алгоритм — это алгоритм "разделяй и властвуй":
- Разделим строку пополам
- Заметим, что повторы делятся на две группы: пересекающие и не пересекающие границу раздела
- Рекурсивно запустимся от каждой половинки — так мы найдем повторы, которые не пересекают границу раздела
- Далее рассмотрим процесс нахождения повторов, которые пересекают границу раздела
Повторы, пересекающие границу раздела, можно разделить на две группы по положению центра повтора.
Так как повторов строке
, мы не можем хранить их в явном виде. Будем хранить повторы блоками вида , где — это длина повтора, а — промежуток индексов, в которых заканчиваются повторы такой длины.Нахождение правых повтров
Рассмотрим строку
, пусть начало в исходной строке —- Предподсчитаем следующие массивы c помощью z-функции:
- , где — наибольший общий префикс
- , где — наибольший общий суффикс
- Переберем длину повтора . Для каждого получим интервал индексов конца повтора в строке : .
- Добавим к ответу, учитывая смещение в исходной строке :
Итоговая асимптотика:
Докажем следующее утверждение для нахождения интервала
:Утверждение: |
, где индекс конца повтора в строке . |
Рассмотрим правый повтор
|
Нахождение левых повтров
Рассмотрим строку
, пусть начало в исходной строке —- Предподсчитаем следующие массивы с помощью z-функции:
- , где — наибольший общий префикс
- , где — наибольший общий суффикс
- Переберем длину повтора . Для каждого получим интервал индексов конца повтора в строке : .
- Добавим к ответу, учитывая смещение в исходной строке :
Итоговая асимптотика:
Докажем следующее утверждение для нахождения интервала
:Утверждение: |
Пусть
|
Асимптотика
Ассимптотика алгоритма "разделяй и властвуй", каждый рекурсивный запуск которого линеен относительно длины строки,
.Количество блоков в ответе также будет
, так как при каждом рекрсивном запуске добавляется блоков для каждой рассмотренной длины повтора, а их количество линейно относительно длины строки.