Algoritmo più veloce per trovare la sottosequenza palindromo più lunga


8

Prima di tutto dobbiamo leggere una parola e la dimensione desiderata.
Quindi dobbiamo trovare il palindromo più lungo creato dai personaggi in questa parola usata nell'ordine.
Ad esempio per size = 7 e word = "abcababac" la risposta è 7 ("abababa").

Postscript: la dimensione della parola è inferiore a 3000.


Per max palindrome intendi che puoi eliminare i caratteri dalla stringa per lasciare un palindromo e vuoi il palindromo più lungo (o rimozione minima)?

1
Nel tuo esempio, c'è anche un cababac di lunghezza 7. I personaggi rimossi sono quindi uno accanto all'altro e alla fine. È consentita una di queste restrizioni? Semplificano notevolmente la ricerca.

6
A questo ha già risposto Stack Overflow: come trovare la sottosequenza palindromica più lunga?

@GenericHuman: la migliore risposta a questa domanda è stata buona per il capitolo del libro di testo che il richiedente stava leggendo. Non è una buona risposta per questo richiedente. Vedi questa domanda: stackoverflow.com/questions/7043778/… invece.
Neil G,

1
Come viene utilizzata la taglia? Dici di volere il "palindromo massimo", quindi se il palindrom più lungo è più lungo o più corto della dimensione indicata?
Gilles 'SO- smetti di essere malvagio' il

Risposte:


6

C'è un algoritmo che prende il nome dall'algoritmo di Manacher, che è veramente veloce, un algoritmo temporale lineare.

Vedi il riferimento di Wikipedia


Postscript: se hai davvero familiarità con Z Algorithm , scoprirai che sono simili.


modificare

Ho appena frainteso il significato del PO (ma non voglio cancellare le informazioni sulla procedura. È in qualche modo utile). Intende la sottosequenza palindromo più lunga di una stringa, quindi la programmazione dinamica sembra buona: dove indica la lunghezza della sottosequenza di palindromo più solitaria di e è la parentesi di Iverson penso che sia proprio come LCS .

fj,k=max(fj,k+1,fj+1,k,2[Sj=Sk]+fj+1,k1),j<kfk,k=1fj,k=0,j>k
fj,kSj..k[P]

4
Stai rispondendo nel caso della sottostringa, ma la domanda riguarda le sottosequenze.

Il primo termine non dovrebbe essere f (j, k-1)?
Abhishek Bansal,

5

L'algoritmo più veloce che mi viene in mente è applicare LCS in modo creativo. Può risolvere questo problema nello spazio O (N ^ 2) e nello spazio O (N ^ 2) dove N è la dimensione della stringa.

LCS (S, reverse (S)) ti darà la più grande sottosequenza palindromica, poiché la più grande sottosequenza palindromica sarà la più grande sottosequenza comune tra la stringa S e il suo contrario.

Ad esempio,
S = "abcababac"
T = "cababacba" (retro di S)
LCS (S, T) = "abababa"


Riesci a sostenere che questo algoritmo sia il più veloce che chiunque possa inventare, come si pone la domanda?
Juho,

@Juho: non posso. :( Questo è l'algoritmo più veloce che conosca. Tuttavia, è stato accettato dal giudice online UVA ( uva.onlinejudge.org/external/114/11404.html ) e in ACM i vincoli del problema sono tali che passerà solo la soluzione ottimizzata. Quindi la soluzione è abbastanza veloce, non sono sicuro del più veloce.
Shashwat

2

Il problema di trovare LPS di una stringa può essere convertito nel trovare la conseguenza comune più lunga di due stringhe. In questo, una stringa sarà originale e la seconda sarà inversa rispetto alla stringa originale.

Il problema della susseguenza comune più lunga è simile al problema di corrispondenza dei motivi, tranne per il fatto che è consentito saltare i caratteri nel testo. Inoltre, l'obiettivo è di restituire solo una partita, che è il più lungo possibile.

LCS può essere risolto in usando Ricorsione e Memoizzazione.O(n2)

Esiste un algoritmo leggermente più veloce scoperto da Masek e Paterson della complessità temporale . Collegamento cartaceo: Masek e PatersonO(n2/lgn)

Altri due algoritmi presentati da Hirschberg per calcolare LCS di due stringhe (dimensione ) e (dimensione ). Sulla base del presupposto che i simboli che possono apparire in queste stringhe provengano da un alfabeto di dimensione (che in realtà è vero nella maggior parte dei casi). Quindi i simboli possono essere memorizzati in memoria usando i bit , che si adatteranno in una parola di memoria. due simboli possono essere confrontati in tempo. Il numero di differenti nella stringa è indicato da , che ovviamente è inferiore sia a che a .AnBmtlog(t)O(1)Bsmt

  1. Questo richiede tempo in cui è la lunghezza di LCS. Viene utilizzato quando si prevede che la lunghezza dell'LCS sia ridotta. Quando risolviamo questo problema utilizzando la Programmazione dinamica, riscontriamo che la maggior parte delle voci nella matrice sono uguali, quindi possiamo usare l'idea di Programmazione dinamica sparsa.O(pn+nlgn)p

  2. Questo algoritmo richiede tempo . Questo è molto efficiente quando la lunghezza di LCS è vicina a , in quel caso sarà vicina a .O(p(m+1p)logn)mO(nlgn)

Procedure dettagliate e algoritmi sono spiegati nel documento di Hirschberg .

Un altro buon algoritmo è proposto da Sohel Rahman che gira nel tempo , dove è il numero totale di coppie ordinate di posizioni in corrispondenza delle stringhe. Non è applicabile quando è l'ordine di , ma ci sono molti casi in cui è l'ordine di . Questo utilizza il concetto RMQ (Range Maximum Query). Collegamento cartaceo: RahmanO(Rloglogn)RRO(n2)Rn


@FrankW, grazie! Ho modificato la risposta. Ora i link sono visibili.
Surendra,

La tua formattazione mancava ancora; controlla la mia modifica per vedere cosa è possibile. I riferimenti all'articolo sono ancora errati perché si basano sul collegamento sempre funzionante, per sempre. Vedi qui per un consiglio; titolo, autori e anno dovrebbero essere indicati (almeno).
Raffaello

Due preoccupazioni su ciò che scrivi: 1) "richiede " non ha senso (dal momento che dà limiti superiori ) e ignorando quello probabilmente sbagliato; Immagino che mostrino i limiti superiori di questi ordini ma gli algoritmi potrebbero essere anche più veloci. 2) Almeno nell'ultimo paragrafo, vuoi . O()OΩ(n2)
Raffaello

-1

Probabilmente mi manca qualcosa, perché mi sembra piuttosto banale: prova ad accoppiare ogni personaggio con un personaggio uguale. Quindi metti il ​​primo personaggio di ogni coppia sul lato sinistro, l'altro personaggio sul lato destro, e se ci sono caratteri rimanenti (cioè personaggi non accoppiati con un altro), quindi scegline uno e mettilo nel Medio.


1
Quando hai (con le parole ), come decideresti se il primo e l'ultimo carattere del palindromo dovrebbero essere o ? È necessario esaminare i contenuti di prima di prendere una decisione se si desidera avere il palindromo più lungo. aubvawbu,v,wabu,v,w
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.