Introducción
Así que he estado perdiendo mi tiempo nuevamente investigando algoritmos de clasificación de sufijos, evaluando nuevas ideas a mano y en código. ¡Pero siempre me cuesta recordar el tipo de mis sufijos! ¿Me puede decir de qué tipo son mis sufijos?
¿Qué más a la izquierda?
Una gran cantidad de algoritmos de clasificación de sufijos (SAIS, KA, mi propio software daware) agrupan los sufijos en diferentes tipos para ordenarlos. Hay dos tipos básicos: de tipo S y tipo L sufijos. Los sufijos tipo S son sufijos que son lexicográficamente menos ( S menor) que el siguiente sufijo y tipo L si es lexicográficamente mayor ( L arger). Un tipo S más a la izquierda ( tipo LMS ) es solo eso: un sufijo de tipo S precedido por un sufijo de tipo L.
¡Lo especial de estos sufijos de tipo LMS es que una vez que los ordenamos, podemos ordenar todos los demás sufijos en tiempo lineal! ¿No es asombroso?
El reto
Dada una cadena, suponga que está terminada por un carácter especial que es menor que cualquier otro carácter en esa cadena (por ejemplo, más pequeño que incluso el byte nulo). Salida de un tipo de corrosponding char para cada sufijo.
Se puede elegir libremente qué char a utilizar para el tipo, pero yo preferiría L, S and *
para L-, S- and LMS-type
siempre y cuando todos ellos son imprimibles ( 0x20 - 0x7E
).
Ejemplo
Dado el mmiissiissiippi
resultado de la cadena (cuando se usa L, S and *
):
LL*SLL*SLL*SLLL
Por ejemplo, el primero L
se debe al hecho de que mmiissiissiippi$
es lexicográficamente mayor que miissiissiippi$
( $
representa el carácter mínimo agregado):
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$ > $
Algunos ejemplos más:
"hello world" -> "L*SSL*L*LLL"
"Hello World" -> "SSSSL*SSLLL"
"53Ab§%5qS" -> "L*SSL*SLL"
Objetivo
No estoy aquí para molestar a Peter Cordes (voy a hacer esto en stackoverflow en algún momento); Soy muy vago, así que, por supuesto, ¡esto es código golf ! La respuesta más corta en bytes gana.
Editar: el orden de los caracteres viene dado por su valor de byte. Eso significa que se comparan deben ser como C de strcmp
.
Edit2: como se indica en la salida de comentarios, debe haber un solo carácter para cada carácter de entrada. Si bien supuse que se entendería como "devolver una cadena", parece que al menos 1 respuesta devuelve una lista de caracteres individuales. Para no invalidar las respuestas existentes, le permitiré devolver una lista de caracteres individuales (o enteros que, cuando se imprimen, dan como resultado solo 1 carácter).
Consejos para tiempo lineal:
- Se puede hacer en 2 iteraciones paralelas hacia adelante o en una única iteración hacia atrás.
- El estado de cada sufijo depende solo de los primeros 2 caracteres y del tipo del segundo.
- Al escanear la entrada en dirección inversa, puede determinar L o S de esta manera:
$t=$c<=>$d?:$t
(PHP 7), donde$c
está el carácter actual$d
del tipo anterior y$t
anterior. - Ver mi respuesta PHP . Mañana otorgaré la recompensa.
c++
cadenas de estilo. Piense en ello como datos binarios.
*
significa
*
significa que el sufijo correspondiente es de tipo left most s-type
. A S-type suffix that is preceeded by a L-type suffix.
.