Parole di Fibonacci


11

Ho riscontrato il seguente problema nel mio vecchio manuale di algoritmo ceco, purtroppo senza suggerimenti o soluzioni.

"Definiamo parole di Fibonacci come , , , dove e sono lettere generali. Come in una data stringa (su un alfabeto potenzialmente grande) riesci a trovare la parola secondaria di Fibonacci più lunga in tempo lineare? "F0=aF1=bFn+2=FnFn+1ab

Conosco una soluzione nel tempo quadratico, ma non posso ridurla a lineare. Qualcuno può indicarmi la giusta direzione?


3
Qual è il nome di questo vecchio manuale di algoritmo ceco ;-)
Saeed,

Le parole secondarie devono essere contigue (cioè fattori) in questo libro?
Klaus Draeger,

Risposte:


12

L'ovvio modo di procedere è la programmazione dinamica: lascia che memorizzi le due lettere per le quali una parola d'ordine di Fibonacci inizia nella posizione , e calcola osservando e . Questo richiede al massimo tempo, perché ci sono solo molti valori logaritmicamente possibili di .F(i,j)ijF(i2,j)F(i1,j+fib(i))O(nlogn)i

Ma ho il sospetto che ci possano essere solo posizioni per le quali è non vuoto (cioè che quando sono presenti due parole Fibonacci della stessa lunghezza possono solo si sovrappongono per una frazione costante della loro lunghezza piuttosto che la maggior parte della loro lunghezza). Le posizioni non vuote di sono le uniche per le quali è necessario eseguire il calcolo (tempo costante) per . Quindi, se il mio sospetto è vero, allora potresti accelerarlo fino a tenendo traccia di un elenco di posizioni non vuote per ciascun valore di e usando l'elenco per per accelerare il calcolo dell'elenco per .O(n/fib(i))F(i2,j)F(i2,j)F(i,j)O(n)ii2i

Se si memorizza in un array, lo spazio rimarrebbe comunque anche dopo lo speedup ma questo potrebbe essere migliorato usando invece una tabella hash. Oppure, in alternativa, è possibile memorizzare in un array ricco di bit con parole -bit (usando l'osservazione che è necessario solo sapere se è vuoto o no; è possibile trovare i due caratteri per ogni sottostringa cercando nelle prime due delle sue posizioni nella stringa di input).FO(nlogn)FO(n) logn


Puoi dirmi perché hai pensato che la programmazione dinamica sarebbe stata la scelta migliore per questo problema? Dove incontreremo il problema se utilizziamo una programmazione statica come C ?
Tarit Goswami,

1
La programmazione dinamica è una tecnica di progettazione di algoritmi, non una classe di linguaggi di programmazione.
David Eppstein,
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.