Introdução
Então, eu perdi meu tempo novamente pesquisando algoritmos de classificação de sufixos, avaliando novas idéias manualmente e em código. Mas sempre luto para lembrar o tipo dos meus sufixos! Você pode me dizer qual é o tipo dos meus sufixos?
Mais à esquerda o que?
Muitos algoritmos de classificação de sufixos (SAIS, KA, meu próprio daware) agrupam sufixos em tipos diferentes para classificá-los. Existem dois tipos básicos: S-tipo e tipo L sufixos. Os sufixos do tipo S são sufixos lexicograficamente menores ( S maller) do que o sufixo a seguir e o tipo L, se for lexicograficamente maior ( L arger). O tipo S mais à esquerda ( tipo LMS ) é exatamente isso: Um sufixo do tipo S precedido por um sufixo do tipo L.
O que há de especial nesses sufixos do tipo LMS é que, quando os classificamos, podemos classificar todos os outros sufixos em tempo linear! Isso não é incrível?
O desafio
Dada uma string, suponha que ela seja finalizada por um caractere especial menor que qualquer outro caractere da string (por exemplo, menor que o byte nulo). Saída de um tipo de caractere corrosivo para cada sufixo.
Você pode escolher livremente qual char para usar para que tipo, mas eu prefiro L, S and *
para L-, S- and LMS-type
contanto que eles são todos de impressão ( 0x20 - 0x7E
).
Exemplo
Dada a mmiissiissiippi
saída da string (ao usar L, S and *
):
LL*SLL*SLL*SLLL
Por exemplo, o primeiro L
se deve ao fato de mmiissiissiippi$
ser lexicograficamente maior que miissiissiippi$
(o $
representa o caractere mínimo adicionado):
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$ > $
Mais alguns exemplos:
"hello world" -> "L*SSL*L*LLL"
"Hello World" -> "SSSSL*SSLLL"
"53Ab§%5qS" -> "L*SSL*SLL"
Objetivo
Não estou aqui para irritar Peter Cordes (vou fazer isso no stackoverflow algum dia); Eu sou apenas muito preguiçoso, então isso é claro, código-golfe ! A resposta mais curta em bytes vence.
Edit: A ordem dos caracteres é dada pelo valor em bytes. Isso significa que comparar deve ser como C's strcmp
.
Edit2: Como indicado na saída de comentários, deve haver um único caractere para cada caractere de entrada. Embora eu tenha assumido que isso seria entendido como "retornar uma string", parece que pelo menos 1 resposta retorna uma lista de caracteres únicos. Para não invalidar as respostas existentes, permitirei que você retorne uma lista de caracteres únicos (ou números inteiros que, quando impressos, resultam em apenas 1 caractere).
Dicas para o tempo linear:
- Isso pode ser feito em 2 iterações para frente paralelas ou em uma única iteração para trás.
- O estado de cada sufixo depende apenas dos 2 primeiros caracteres e do tipo do segundo.
- Digitalizando a entrada na direção inversa, é possível determinar L ou S assim:
$t=$c<=>$d?:$t
(PHP 7), onde$c
é o caractere atual,$d
o tipo anterior e$t
o anterior. - Veja minha resposta em PHP . Amanhã vou premiar a recompensa.
c++
strings de estilo. Pense nisso como dados binários.
*
significa isso ?
*
significa que o sufixo correspondente é do tipo left most s-type
. A S-type suffix that is preceeded by a L-type suffix.
.