Декомпозиция Линдона — различия между версиями
(→Алгоритм Дюваля) |
(→Алгоритм Дюваля) |
||
Строка 69: | Строка 69: | ||
==Алгоритм Дюваля== | ==Алгоритм Дюваля== | ||
Алгоритм Дюваля (англ. ''Duval's algorithm'') находит для данной строки длины <tex>n</tex> декомпозицию Линдона за время <tex>O(n)</tex> с использованием <tex>O(1)</tex> дополнительной памяти. | Алгоритм Дюваля (англ. ''Duval's algorithm'') находит для данной строки длины <tex>n</tex> декомпозицию Линдона за время <tex>O(n)</tex> с использованием <tex>O(1)</tex> дополнительной памяти. | ||
+ | |||
+ | {{Определение | ||
+ | |id=def3 | ||
+ | |definition='''Предпростая строка''' {{---}} строка <tex>s</tex>, такая что <tex>s = w + w + ... + w + w'</tex>, где <tex>w</tex> {{---}} некоторая простая строка, а <tex>w'</tex> - некоторый префикс строки <tex>w</tex>. | ||
+ | }} | ||
+ | |||
+ | string s // входная строка | ||
+ | string[] words // декомпозиция | ||
+ | n <tex>\leftarrow</tex> |s| | ||
+ | i <tex>\leftarrow</tex> 0 | ||
+ | w <tex>\leftarrow</tex> 0 | ||
+ | while (i < n) { | ||
+ | j <tex>\leftarrow</tex> i + 1 | ||
+ | k <tex>\leftarrow</tex> i | ||
+ | while (j < n and s[k] <= s[j]) { | ||
+ | if s[k] < s[j] | ||
+ | k <tex>\leftarrow</tex> i | ||
+ | else | ||
+ | k <tex>\leftarrow</tex> k + 1 | ||
+ | j <tex>\leftarrow</tex> j + 1 | ||
+ | } | ||
+ | while (i <= k) { | ||
+ | words[w] <tex>\leftarrow</tex> s[i..j-k] | ||
+ | w <tex>\leftarrow</tex> w + 1 | ||
+ | i <tex>\leftarrow</tex> i + j - k; | ||
+ | } | ||
+ | } |
Версия 21:55, 1 мая 2014
Основные определения
Декомпозиция Линдона была изобретена Роджером Линдоном (англ. Roger Lyndon) в 1954 году. Она используется для нахождения лексикографически минимального и максимального суффиксов строки.
Определение: |
Простая строка — строка, которая строго лексикографически меньше любого своего суффикса. |
Определение: |
Декомпозиция Линдона (англ. Lyndon decomposition) строки | — её разложение , где строки просты, и при этом .
Существование и единственность
Лемма: |
1. 2. — простая |
Доказательство: |
1. Так как , и , 2. Пусть — суффикс строки1) 2) 3) — суффикс . Так как — простая, , . Так как — простая, и |
Теорема: |
Можно построить декомпозицию Линдона любой строки , причем единственным образом. |
Доказательство: |
1. Существование. Разобьем строку на символы. Будем их склеивать, если подряд идущие символы: . Так как символ — простая строка, по лемме — тоже простая и . Далее склеиваем строки, не удовлетворяющие условию . Это конечный процесс, так как длина строки конечна получим нужное разбиение.Пусть существует хотя бы одно разбиение строки на простые слова. Возьмем разбиение строки на простые слова (без условия ) такое, чтобы было минимально. Пусть в нем есть , тогда эти строки можно сконкатернировать получим разбиение с меньшим числом слов — противоречие с выбором .Получили: — минимально нет2. Единственность. Пусть существует несколько разбиений , удовлетворяющих условию теоремы. Сравним длины первых двух слов и , если , сравним вторые и так далее. Если у всех слов длины одинаковы, то разбиения совпадают — противоречие. Иначе Покажем, что такого не может быть:1) Пусть Тогда , где — префикс , Получаем: (так как простая и по определению меньше своего суффикса), (так как — префикс), (по условию разбиения), (их начало совпадает, и по предположению. Получили противоречие: .2) Пусть То есть не может быть строк — проверяется аналогично. несовпадающей длины разбиения равны. |
Алгоритм Дюваля
Алгоритм Дюваля (англ. Duval's algorithm) находит для данной строки длины
декомпозицию Линдона за время с использованием дополнительной памяти.
Определение: |
Предпростая строка — строка | , такая что , где — некоторая простая строка, а - некоторый префикс строки .
string s // входная строка string[] words // декомпозиция n|s| i 0 w 0 while (i < n) { j i + 1 k i while (j < n and s[k] <= s[j]) { if s[k] < s[j] k i else k k + 1 j j + 1 } while (i <= k) { words[w] s[i..j-k] w w + 1 i i + j - k; } }