Вступ
Тож я знову витрачаю час на дослідження алгоритмів сортування суфіксів, оцінювання нових ідей вручну та в коді. Але я завжди намагаюся запам'ятати тип моїх суфіксів! Чи можете ви сказати, до якого типу належать мої суфікси?
Зліва-найбільше що?
Дуже багато алгоритмів сортування суфіксів (SAIS, KA, мій власний програмний засіб) групують суфікси у різні типи, щоб сортувати їх. Існує два основні типи: суфікси типу 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"
Мета
Я не тут, щоб дратувати Пітера Кордеса (я так збираюсь робити це колись по потоку); Я просто дуже ледачий, тому це звичайно код-гольф ! Виграє найкоротша відповідь у байтах.
Редагувати: Порядок символів задається їх байтним значенням. Це означає порівняння повинно бути , як C - х strcmp
.
Edit2: Як зазначено у коментарях, вихід повинен бути одним символом для кожного вхідного символу. Хоча я припускав, що це буде розумітися як "повернути рядок", здається, щонайменше 1 відповідь повертає список одиночних символів. Щоб не визнати недійсними відповіді, я дозволю вам повернути список одиничних символів (або цілих чисел, які при друкуванні дають лише 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.
.