Intro
J'ai donc perdu mon temps à rechercher des algorithmes de tri de suffixes, à évaluer de nouvelles idées à la main et dans le code. Mais j'ai toujours du mal à me souvenir du type de mes suffixes! Pouvez-vous me dire de quel type sont mes suffixes?
À gauche quoi?
De nombreux algorithmes de tri des suffixes (SAIS, KA, mon propre daware) regroupent les suffixes en différents types afin de les trier. Il existe deux types de base: type S et de type L suffixes. Les suffixes de type S sont des suffixes qui sont lexicographiquement moins ( S maller) que le suffixe suivant et le type L s'il est lexicographiquement plus grand ( L arger). Un type S le plus à gauche ( type LMS ) n'est que cela: un suffixe de type S précédé d'un suffixe de type L.
La particularité de ces suffixes de type LMS est qu'une fois que nous les avons triés, nous pouvons trier tous les autres suffixes en temps linéaire! N'est-ce pas génial?
Le défi
Étant donné une chaîne, supposons qu'elle se termine par un caractère spécial qui est inférieur à tout autre caractère de cette chaîne (par exemple, plus petit que même l'octet nul). Sortez un caractère corrospondant pour chaque suffixe.
Vous pouvez librement choisir ombles à utiliser pour quel type , mais je préfère L, S and *
pour L-, S- and LMS-type
aussi longtemps qu'ils sont imprimables ( 0x20 - 0x7E
).
Exemple
Étant donné la mmiissiissiippi
sortie de la chaîne (lors de l'utilisation L, S and *
):
LL*SLL*SLL*SLLL
Par exemple, le premier L
est dû au fait qu'il mmiissiissiippi$
est lexicographiquement supérieur à miissiissiippi$
(le $
représente le caractère minimal ajouté):
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$ > $
Quelques exemples supplémentaires:
"hello world" -> "L*SSL*L*LLL"
"Hello World" -> "SSSSL*SSLLL"
"53Ab§%5qS" -> "L*SSL*SLL"
Objectif
Je ne suis pas ici pour ennuyer Peter Cordes (je vais faire ça sur stackoverflow un jour); Je suis juste très paresseux donc c'est bien sûr du code-golf ! La réponse la plus courte en octets l'emporte.
Edit: l'ordre des caractères est donné par leur valeur d'octet. Cela signifie comparer devrait être comme C de strcmp
.
Edit2: Comme indiqué dans les commentaires, la sortie doit être un seul caractère pour chaque caractère d'entrée. Bien que je suppose que cela serait compris comme "renvoyer une chaîne", il semble qu'au moins 1 réponse renvoie une liste de caractères uniques. Afin de ne pas invalider les réponses existantes, je vous permettrai de renvoyer une liste de caractères uniques (ou entiers qui, une fois imprimés, ne donneront que 1 caractère).
Conseils pour le temps linéaire:
- Cela peut être fait en 2 itérations en avant parallèles ou en une seule itération en arrière.
- L'état de chaque suffixe ne dépend que des 2 premiers caractères et du type du second.
- En balayant l'entrée dans le sens inverse, vous pouvez déterminer L ou S comme ceci:
$t=$c<=>$d?:$t
(PHP 7), où$c
est le caractère actuel$d
du type précédent et$t
précédent. - Voir ma réponse PHP . Demain, je décernerai la prime.
c++
chaînes de style. Considérez-le comme des données binaires.
*
dire?
*
signifie que le suffixe correspondant est de type left most s-type
. A S-type suffix that is preceeded by a L-type suffix.
.