вступление
Поэтому я снова тратил время на исследование алгоритмов сортировки суффиксов, оценку новых идей вручную и в коде. Но я всегда пытаюсь вспомнить тип моих суффиксов! Можете ли вы сказать мне, какой тип моих суффиксов?
Левый самый что?
Многие алгоритмы сортировки суффиксов (SAIS, KA, мое собственное daware) группируют суффиксы в разные типы для их сортировки. Существует два основных типа: суффиксы S-типа и L-типа . Суффиксы S-типа - это суффиксы, которые лексикографически меньше ( S maller), чем следующий суффикс, и L-типа, если они лексикографически больше ( L arger). Крайний левый S-тип ( LMS-тип ) - это просто суффикс S-типа, которому предшествует суффикс L-типа .
Особенность этих суффиксов типа LMS заключается в том, что как только мы их отсортируем, мы можем отсортировать все другие суффиксы за линейное время! Разве это не круто?
Соревнование
Учитывая, что строка предполагает, что она заканчивается специальным символом, который меньше, чем любой другой символ в этой строке (например, меньше, чем даже нулевой байт). Выведите тип соответствующего символа для каждого суффикса.
Вы можете свободно выбирать, какой символ использовать для какого типа, но я бы предпочел, L, S and *
чтобы L-, S- and LMS-type
все они печатались ( 0x20 - 0x7E
).
пример
Учитывая mmiissiissiippi
вывод строки (при использовании L, S and *
):
LL*SLL*SLL*SLLL
Например, первое L
связано с тем, что mmiissiissiippi$
лексикографически больше, чем miissiissiippi$
( $
символ представляет добавленный минимальный символ):
L - mmiissiissiippi$ > miissiissiippi$
L - miissiissiippi$ > iissiissiippi$
* - iissiissiippi$ < issiissiippi and preceeded by L
S - issiissiippi$ < ssiissiippi$
L - ssiissiippi$ > siissiippi$
L - siissiippi$ > iissiippi$
* - iissiippi$ < issiippi$ and preceeded by L
S - issiippi$ < ssiippi$
L - ssiippi$ > siippi$
L - siippi$ > iippi$
* - iippi$ < ippi$ and preceeded by L
S - ippi$ < ppi$
L - ppi$ > pi$
L - pi$ > i$
L - i$ > $
Еще несколько примеров:
"hello world" -> "L*SSL*L*LLL"
"Hello World" -> "SSSSL*SSLLL"
"53Ab§%5qS" -> "L*SSL*SLL"
Цель
Я здесь не для того, чтобы раздражать Питера Кордеса (я так собираюсь когда-нибудь сделать это на stackoverflow); Я просто очень ленив, так что это, конечно, код-гольф ! Самый короткий ответ в байтах побеждает.
Изменить: порядок символов определяется их байтовым значением. Это означает, что сравнение должно быть как у strcmp
.
Edit2: как указано в выводе комментариев должен быть один символ для каждого входного символа. Хотя я предполагал, что это будет пониматься как «вернуть строку», кажется, что хотя бы один ответ возвращает список из отдельных символов. Чтобы не сделать недействительными существующие ответы, я позволю вам вернуть список из отдельных символов (или целых чисел, которые при печати приводят только к 1 символу).
Советы по линейному времени:
- Это может быть сделано в 2 параллельных прямых итерациях или в одной обратной итерации.
- Состояние каждого суффикса зависит только от первых двух символов и типа второго.
- Сканируя ввод в обратном направлении, вы можете определить L или S следующим образом:
$t=$c<=>$d?:$t
(PHP 7), где$c
текущий символ$d
предыдущего и$t
предыдущего типа. - Смотрите мой ответ PHP . Завтра я буду награждать награду.
c++
строк стиля. Думайте об этом как двоичные данные.
*
значит?
*
означает, что соответствующий суффикс имеет тип left most s-type
. A S-type suffix that is preceeded by a L-type suffix.
,