Intro
Quindi sto sprecando di nuovo il mio tempo alla ricerca di algoritmi di ordinamento dei suffissi, valutando nuove idee a mano e nel codice. Ma faccio sempre fatica a ricordare il tipo dei miei suffissi! Puoi dirmi di che tipo sono i miei suffissi?
Più a sinistra cosa?
Molti algoritmi di ordinamento dei suffissi (SAIS, KA, il mio daware) raggruppano i suffissi in diversi tipi per ordinarli. Ci sono due tipi fondamentali: di tipo S e L-type suffissi. I suffissi di tipo S sono suffissi lessicograficamente inferiori ( S maller) rispetto al suffisso seguente e di tipo L se è lessicograficamente maggiore ( arger L ). Un tipo S più a sinistra ( tipo LMS ) è proprio questo: un suffisso di tipo S preceduto da un suffisso di tipo L.
La particolarità di questi suffissi di tipo LMS è che una volta ordinati li possiamo ordinare tutti gli altri suffissi in tempo lineare! Non è fantastico?
La sfida
Data una stringa, supponiamo che sia terminata da un carattere speciale che è inferiore a qualsiasi altro carattere in quella stringa (ad es. Più piccolo del byte nullo). Emette un carattere corrosponding di tipo per ciascun suffisso.
Si può liberamente scegliere quale carattere da utilizzare per quale tipo, ma io preferirei L, S and *
per L-, S- and LMS-type
tutto il tempo che sono tutti stampabili ( 0x20 - 0x7E
).
Esempio
Dato l' mmiissiissiippi
output della stringa (quando si utilizza L, S and *
):
LL*SLL*SLL*SLLL
Ad esempio il primo L
è dovuto al fatto che mmiissiissiippi$
è lessicograficamente maggiore di miissiissiippi$
(il $
rappresenta il carattere minimo aggiunto):
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$ > $
Alcuni altri esempi:
"hello world" -> "L*SSL*L*LLL"
"Hello World" -> "SSSSL*SSLLL"
"53Ab§%5qS" -> "L*SSL*SLL"
Obbiettivo
Non sono qui per infastidire Peter Cordes (un giorno lo farò su StackOverflow); Sono solo molto pigro, quindi questo è ovviamente code-golf ! Vince la risposta più breve in byte.
Modifica: l'ordine dei caratteri è dato dal loro valore in byte. Ciò significa confrontare dovrebbe essere come C di strcmp
.
Modifica2: come indicato nei commenti, l'output deve essere un singolo carattere per ciascun carattere di input. Mentre supponevo che sarebbe stato inteso come "restituisci una stringa" sembra che almeno 1 risposta restituisca un elenco di singoli caratteri. Per non invalidare le risposte esistenti, ti permetterò di restituire un elenco di singoli caratteri (o numeri interi che, se stampati, producono solo 1 carattere).
Suggerimenti per il tempo lineare:
- Può essere eseguito in 2 iterazioni parallele in avanti o in una singola iterazione all'indietro.
- Lo stato di ciascun suffisso dipende solo dai primi 2 caratteri e dal tipo del secondo.
- Scansionando l'ingresso in direzione inversa è possibile determinare L o S in questo modo:
$t=$c<=>$d?:$t
(PHP 7), dove$c
è il carattere corrente$d
del tipo precedente e$t
precedente. - Vedi la mia risposta PHP . Domani assegnerò la taglia.
c++
stringhe di stile. Pensalo come dati binari.
*
significa?
*
significa che il suffisso corrispondente è di tipo left most s-type
. A S-type suffix that is preceeded by a L-type suffix.
.