3622
правки
Изменения
Нет описания правки
Декомпозиция Линдона была изобретена Роджером Линдоном (англ. ''Roger Lyndon'') в 1954 году. Она используется для нахождения лексикографически минимального и максимального суффиксов строки, а также лексикографически минимального циклического сдвига.
==Основные определения==
2. <tex>s + t</tex> {{---}} простая
|proof=
1. Так как <tex>s < t</tex>, то <tex>\mathcal {9} exists i : s[i] < t[i]</tex> и <tex>s[j] = t[j]</tex>, <tex>j < i \rightarrow Rightarrow s + t < t</tex>
2. Пусть <tex>u</tex> {{---}} суффикс строки <tex>s + t</tex>. Тогда рассмотрим <tex> 3 </tex> возможных случая:
}}
{{Теорема
|id=theorem
|author=Чен-Линдон-Фокс
|statement=Можно построить декомпозицию Линдона любой строки <tex>s</tex>, причем единственным образом.
|proof=
1. Существование.
2. Единственность.
Сравним длины первых двух слов <tex>s_1</tex> и <tex>s_1'</tex>, если <tex>|s_1| = |s_1'|</tex>, сравним вторые и так далее.
Если у всех слов длины одинаковы, то разбиения совпадают {{---}} противоречие.
Иначе <tex>\mathcal {9} exists s_i : |s_i| \neq |s_i'|</tex>.
Покажем, что такого не может быть:
1) Пусть <tex>|s_i| > |s_i'|</tex>Тогда , тогда <tex>s_i = s_i's_{i+1}'...t</tex>, где <tex>t</tex> {{---}} префикс <tex>s_{j+1}'</tex>, <tex>i \leqslant < j</tex>. Получаем: <tex>s_i < t</tex> (, так как <tex>s_i</tex> простая и по определению меньше своего суффикса),<tex>t < s_{j+1}'</tex> (так как <tex>t</tex> {{---}} префикс???),
<tex>s_{j+1}' < s_i'</tex> (по условию разбиения),
<tex>s_i' < s_i</tex> (их начало совпадает, и <tex>|s_i| < |s_i'|</tex> по предположению.
Получили противоречие: <tex>s_i < s_i</tex>.
2) Пусть Случай <tex>|s_i| < |s_i'|</tex> {{---}} проверяется аналогичносимметричен разобранному. То есть не может быть строк <tex>s_i</tex> несовпадающей длины <tex>\rightarrow</tex> , значит, разбиения равны.
}}
Дополнительная память требуется только на три указателя: <tex>i, j, k</tex>.
Внешний цикл <tex>\mathrm{while}</tex> делает не более <tex>n</tex> итераций, поскольку в конце каждой его итерации к результату добавляется как минимум один символ (а всего символов <tex>n</tex>).
Оценим теперь количество итераций первого вложенного цикла <tex>\mathrm{while}</tex>. Для этого рассмотрим второй вложенный цикл <tex>\mathrm{while}</tex> {{---}} он при каждом своём запуске выводит некоторое количество <tex>r \geqslant 1</tex> копий одной и той же простой строки некоторой длины <tex>p = j - k</tex>. Заметим, что строка <tex>s_2</tex> является предпростой, причём её простые строки имеют длину как раз <tex>p</tex>, т.е. её длина не превосходит <tex>r \cdot p + p - 1</tex>. Поскольку длина строки <tex>s_2</tex> равна <tex>j - i</tex>, а указатель <tex>j</tex> увеличивается по единице на каждой итерации первого вложенного цикла <tex>\mathrm{while}</tex>, то этот цикл выполнит не более <tex>r \cdot p + p - 2</tex> итераций. Худшим случаем является случай <tex>r = 1</tex>, и мы получаем, что первый вложенный цикл <tex>\mathrm{while}</tex> всякий раз выполняет не более <tex>2p - 2</tex> итераций. Вспоминая, что всего выводится <tex>n</tex> символов, получаем, что для вывода <tex>n</tex> символов требуется не более <tex>2n - 2</tex> итераций первого вложенного <tex>\mathrm{while}</tex>. Следовательно, алгоритм Дюваля выполняется за <tex>O(n)</tex>.
Легко оценить и число сравнений символов, выполняемых алгоритмом Дюваля. Поскольку каждая итерация первого вложенного цикла <tex>\mathrm{while}</tex> производит два сравнения символов, а также одно сравнение производится после последней итерации цикла, то общее число сравнений символов не превосходит <tex>4n - 3</tex>.