Изменения

Перейти к: навигация, поиск

Алгоритм Мейна-Лоренца

285 байт добавлено, 21:34, 30 апреля 2015
Нет описания правки
# Разобьем ее на две строки <tex> u </tex> и <tex> v </tex>.
# Предподсчитаем следующие массивы c помощью [[Z-функция | Z-функции]]:
#* <tex> RP[i] = lcp(v[i \dotsc v.len], \, v) </tex>, то есть наибольший общий префикс строк <tex> v[i \dotsc v.len] </tex> и <tex> v </tex>. Нахождение <tex>lcp(a,\,b[i \dotsc b.len])</tex> можно осуществить следующим образом: вычислим для строки <math> a+'\#'+b </math> [[Z-функция | Z-функцию]]. Очевидно, что в таком случае массивом <tex>lcp</tex> будет массив значений Z-функции, начиная с индекса <tex> a.len + 2 </tex>.
#* <tex> RS[i] = lcs(v[1 \dotsc i], \, u) </tex>, то есть наибольший общий суффикс строк <tex> v[1 \dotsc i]</tex> и <tex> u </tex>. Нахождение <tex>lcs(a,\,b[1 \dotsc i)</tex> можно осуществить следующим образом: вычислим для строки <math> reverse(a)+'\#'+reverse(b) </math> [[Z-функция | Z-функцию]]. Очевидно, что в таком случае массивом <tex>lcs</tex> будет перевернутый массив значений Z-функции, начиная с индекса <tex> a.len + 2 </tex>.
# Переберем длину повтора <tex> 2p </tex> и будем искать все повторы такой длины: для каждого <tex> p \in [1, \, t.len /2]</tex> получим интервал индексов конца повтора в строке <tex> v </tex>: <tex> [x, y] </tex> (по формуле, которую докажем позднее). Добавим полученный интервал к ответу, учитывая смещение в исходной строке <tex> s </tex> : <tex>(2p, x + shift + u.len, y + shift + u.len) </tex>
{{Утверждение
|id=kindscount
|statement=<math>2p -RS[p] \leqslant i \leqslant p - RP[p + 1]</math>, где <tex>i</tex> {{---}} индекс конца повтора длины <tex>2p</tex> в строке <tex>v</tex>.
|proof= Рассмотрим правый повтор <tex>ww</tex>.<br>
Обозначим как <tex>k</tex> ту часть первой полвины повтора, которая принадлежит <tex>u</tex>, а как <tex>l</tex> {{---}} ту часть первого половины, которая принадлежит <tex>v</tex>. Равные им подстроки во первой половине обозначим как <tex>m</tex> и <tex>n</tex>(см. рисунок).
<i>Разбиение строки <tex>t</tex>, с индексацией <tex>u</tex> и <tex>v</tex>:</i><br>
[[Файл:RightRepetition.png|600px]]<br>
Пусть <tex> b </tex> {{---}} длина <tex>k</tex>.<br>
{{Утверждение
|id=kindscount
|statement=<math> p - LS[u.len - p] \leqslant i \leqslant LP[u.len - p + 1] </math>, где <tex>i</tex> {{---}} индекс конца повтора длины <tex>2p</tex> в строке <tex>v</tex>.
|proof= Рассмотрим правый повтор <tex>ww</tex>.<br>
Обозначим как <tex>m</tex> ту часть первой второй повтора, которая принадлежит <tex>u</tex>, а как <tex>n</tex> {{---}} ту часть второго половины, которая принадлежит <tex>v</tex>. Равные им подстроки во второй половине обозначим как <tex>k</tex> и <tex>l</tex>(см. рисунок).
<i>Разбиение строки <tex>t</tex>, с индексацией <tex>u</tex> и <tex>v</tex>:</i><br>
[[Файл:LeftRepetition.png|600px]]<br>
Асимптотика алгоритма "разделяй и властвуй", каждый рекурсивный запуск которого линеен относительно длины строки, <tex> O(n \log n) </tex> из рекурентного соотношения <tex>T(n)=2T(n/2)+O(n)</tex> (аналогичное доказательство для [[Сортировка слиянием | сортировки слиянием]]).
Количество блоков в ответе также будет <tex> O(n \log n) </tex>: на каждом рекурсивном запуске при рассмотрении пересекающих повторов, которые пересекают границу раздела повторов , добавляется <tex> O(1) </tex> блоков для каждой рассмотренной длины повтора (их количество линейно относительно длины строки), из чего получаем аналогичное рекурентное соотношение <tex>M(n)=2M(n/2)+O(n)</tex>.
== См. также ==
102
правки

Навигация