97
правок
Изменения
описание алгоритма
== Постановка задачи ==
Дана циклическая строка <tex>s[0 .. n - 1]</tex>. Суффиксом циклической строки <tex>s</tex> называется строка <tex>s[i .. n - 1] + s[0 .. i - 1], i < n </tex>(будем называть такую строкую суффиксом под номером i). Требуется отсортировать все её суффиксы в порядке лексикографической сортировки.
== Решение ==
== Описание алгоритма ==
На нулевой итерации мы должны отсортировать отсортируем циклические подстроки длины <tex>1</tex>, т.е. первые символы строк, и разделить разделим их на классы эквивалентности (одинаковые символы должны быть отнесены к одному классу эквивалентности). Это можно сделать сортировкой При помощи [[Сортировка подсчетом. Для каждого символа посчитаем, сколько раз он встретился. Потом по этой информации восстановим |сортировки подсчетом]] построим массив <tex>p</tex>, содержащий номера суффиксов, отсортированных в лексикографическом порядке. После этого проходом по По этому массиву <tex>p</tex> и сравнением символов строится построим массив классов эквивалентности <tex>c</tex>.
Заметим, что циклическая подстрока длины <tex>2^k</tex> состоит из двух подстрок длины <tex>2^{k-1}</tex>, которые мы можем сравнивать между собой за <tex>O(1)</tex>, используя информацию с предыдущей итерации — номера классов эквивалентности <tex>c</tex>. Таким образом, для подстроки длины <tex>2^k</tex>, начинающейся в позиции <tex>i</tex>, вся необходимая информация содержится в паре чисел <tex>(\textless c[i], c[i + 2^{k-1}])\textgreater </tex>.
Осталось только пересчитать номера классов эквивалентности <tex>c</tex>, просто пройдя по полученной новой перестановке <tex>p</tex> и сравнивая соседние элементы (опять же, сравнивая как пары двух чисел).
==Пример==
sorted_by2 = '''int'''[str.length]
'''for''' i = 0 .. str.length
// сортируем по первой половине
// сортировка устойчивая, значит получим целиком отсортированные подстроки