Алгоритм Мейна-Лоренца — различия между версиями
Mariashka (обсуждение | вклад) |
Mariashka (обсуждение | вклад) |
||
Строка 24: | Строка 24: | ||
Обозначим как <tex>k</tex> ту часть первой полвины повтора, которая принадлежит <tex>u</tex>, а как <tex>l</tex> {{---}} ту часть первого половины, которая принадлежит <tex>v</tex>. Равные им подстроки во первой половине обозначим как <tex>m</tex> и <tex>n</tex>(см. рисунок). | Обозначим как <tex>k</tex> ту часть первой полвины повтора, которая принадлежит <tex>u</tex>, а как <tex>l</tex> {{---}} ту часть первого половины, которая принадлежит <tex>v</tex>. Равные им подстроки во первой половине обозначим как <tex>m</tex> и <tex>n</tex>(см. рисунок). | ||
− | + | <i>Разбиение строки <tex>t</tex>:</i><br> | |
+ | [[Файл:RightRepetition.png|600px]]<br> | ||
Пусть <tex> b </tex> {{---}} длина <tex>k</tex>.<br> | Пусть <tex> b </tex> {{---}} длина <tex>k</tex>.<br> | ||
Заметим, что <tex>w = k + l = m + n</tex> и <tex> k = m, l = n </tex>. <br> | Заметим, что <tex>w = k + l = m + n</tex> и <tex> k = m, l = n </tex>. <br> | ||
Строка 47: | Строка 48: | ||
Обозначим как <tex>m</tex> ту часть первой второй повтора, которая принадлежит <tex>u</tex>, а как <tex>n</tex> {{---}} ту часть второго половины, которая принадлежит <tex>v</tex>. Равные им подстроки во второй половине обозначим как <tex>k</tex> и <tex>l</tex>(см. рисунок). | Обозначим как <tex>m</tex> ту часть первой второй повтора, которая принадлежит <tex>u</tex>, а как <tex>n</tex> {{---}} ту часть второго половины, которая принадлежит <tex>v</tex>. Равные им подстроки во второй половине обозначим как <tex>k</tex> и <tex>l</tex>(см. рисунок). | ||
− | + | <i>Разбиение строки <tex>t</tex>:</i><br> | |
+ | [[Файл:LeftRepetition.png|600px]]<br> | ||
+ | |||
Пусть <tex> b </tex> {{---}} длина <tex>k+l+m</tex>. | Пусть <tex> b </tex> {{---}} длина <tex>k+l+m</tex>. | ||
Заметим, что <tex>w = k + l = m + n</tex> и <tex> k = m, l = n </tex>. <br> | Заметим, что <tex>w = k + l = m + n</tex> и <tex> k = m, l = n </tex>. <br> | ||
Строка 61: | Строка 64: | ||
Количество блоков в ответе также будет <tex> O(n \log n) </tex>: при каждом рекурсивном запуске добавляется <tex> O(1) </tex> блоков для каждой рассмотренной длины повтора (их количество линейно относительно длины строки), из чего получаем аналогичное рекурентное соотношение <tex>M(n)=2M(n/2)+O(n)</tex>. | Количество блоков в ответе также будет <tex> O(n \log n) </tex>: при каждом рекурсивном запуске добавляется <tex> O(1) </tex> блоков для каждой рассмотренной длины повтора (их количество линейно относительно длины строки), из чего получаем аналогичное рекурентное соотношение <tex>M(n)=2M(n/2)+O(n)</tex>. | ||
+ | |||
+ | == См. также == | ||
+ | |||
+ | * [[Алгоритм Ландау-Шмидта]] | ||
+ | * [[Алгоритм Крочемора]] | ||
== Источники информации == | == Источники информации == | ||
* ''Main, M., Lorentz, R.J.'' — '''An O(n log n) Algorithm for Finding All Repetitions in a String'''. 1982 | * ''Main, M., Lorentz, R.J.'' — '''An O(n log n) Algorithm for Finding All Repetitions in a String'''. 1982 | ||
* ''Билл Смит'' — '''Методы и алгоритмы вычислений на строках'''. Пер. с англ.{{---}} М.:Издательский дом "Вильямс", 2006. ISBN 5-8459-1081-1 | * ''Билл Смит'' — '''Методы и алгоритмы вычислений на строках'''. Пер. с англ.{{---}} М.:Издательский дом "Вильямс", 2006. ISBN 5-8459-1081-1 | ||
+ | * [http://e-maxx.ru/algo/string_tandems MAXimal :: algo :: Поиск всех тандемных повторов в строке. Алгоритм Мейна-Лоренца] | ||
− | |||
− | |||
− | |||
[[Категория: Алгоритмы и структуры данных]] | [[Категория: Алгоритмы и структуры данных]] | ||
[[Категория: Основные определения. Простые комбинаторные свойства слов]] | [[Категория: Основные определения. Простые комбинаторные свойства слов]] |
Версия 19:30, 30 апреля 2015
Алгоритм Мейна-Лоренца (англ. Main-Lorentz algorithm) — алгоритм на строках, позволяющий найти все повторы в строке за
Содержание
Алгоритм
Так как повторов строке
, мы не можем хранить их в явном виде. Будем хранить несколько подряд идущих (по индексу конца) повторов одной длины блоками вида , где — это длина повтора, а — промежуток индексов, в каждом из которых заканчивается повтор такой длины. Для каждой длины может быть несколько блоков.Данный алгоритм — это алгоритм типа "разделяй и властвуй": разделим строку пополам, рекурсивно запустимся от каждой половинки — так мы найдем повторы, которые не пересекают границу раздела. Далее рассмотрим процесс нахождения повторов, которые пересекают границу раздела. Их можно разделить на две группы по положению центра повтора: правые и левые.
Нахождение правых повтров
Рассмотрим строку
- Разобьем ее на две строки и .
- Предподсчитаем следующие массивы c помощью Z-функции:
- Z-функцию. Очевидно, что в таком случае массивом будет массив значений Z-функции, начиная с индекса . , то есть наибольший общий префикс строк и . Нахождение можно осуществить следующим образом: вычислим для строки
- Z-функцию. Очевидно, что в таком случае массивом будет перевернутый массив значений Z-функции, начиная с индекса . , то есть наибольший общий суффикс строк и . Нахождение можно осуществить следующим образом: вычислим для строки
- Переберем длину повтора и будем искать все повторы такой длины: для каждого получим интервал индексов конца повтора в строке : (по формуле, которую докажем позднее). Добавим полученный интервал к ответу, учитывая смещение в исходной строке :
Итоговая асимптотика:
Докажем следующее утверждение для нахождения интервала
:Нахождение левых повтров
Левые повторы находим аналогично правым, кроме вычисления интервала Z-функции массивы:
для заданного и, как следствие, предподсчета. Предподсчитаем с помощью- , то есть наибольший общий префикс строк и
- , то есть наибольший общий суффикс строк и
Докажем следующее утверждение для нахождения интервала
:Утверждение: |
Рассмотрим правый повтор Пусть
|
Асимптотика
Асимптотика алгоритма "разделяй и властвуй", каждый рекурсивный запуск которого линеен относительно длины строки, сортировки слиянием).
из рекурентного соотношения (аналогичное доказательство дляКоличество блоков в ответе также будет
: при каждом рекурсивном запуске добавляется блоков для каждой рассмотренной длины повтора (их количество линейно относительно длины строки), из чего получаем аналогичное рекурентное соотношение .См. также
Источники информации
- Main, M., Lorentz, R.J. — An O(n log n) Algorithm for Finding All Repetitions in a String. 1982
- Билл Смит — Методы и алгоритмы вычислений на строках. Пер. с англ.— М.:Издательский дом "Вильямс", 2006. ISBN 5-8459-1081-1
- MAXimal :: algo :: Поиск всех тандемных повторов в строке. Алгоритм Мейна-Лоренца