Ecco una soluzione O (n) (presupponendo dimensioni alfabeto fisse e accesso al dizionario O (1)).
Utilizzare una tabella di frequenza singola che conta per i caratteri in seq1 e in basso per caratteri in seq2. Avremo una finestra corrispondente se questo istogramma prende sempre lo stesso valore (poiché ciò significa che dobbiamo avere un numero identico di caratteri intermedi).
Quindi usiamo un dizionario per memorizzare i valori precedenti per l'istogramma.
implementazione di Python:
def find_window(seq1,seq2):
"""Yield length of matching windows"""
D={} # Dictionary with key=histogram, value = first position where this happens
H=[0]*26 # H[x] is count of x in seq1 - count of x in seq2
D[tuple(H)]=-1
for i,(a,b) in enumerate(zip(seq1,seq2)):
a=ord(a)-ord('A')
b=ord(b)-ord('A')
H[a]+=1
H[b]-=1
key=tuple(H)
if key in D:
yield i-D[key]
if key not in D:
D[key]=i
print max(find_window("ABCDEFG","DBCAPFG"))
Se tu avessi un alfabeto più grande è possibile utilizzare una tecnica simile solo la memorizzazione di un valore di hash invece della piena istogramma. Ad esempio potresti semplicemente scegliere un codice casuale per ogni carattere e aggiungere il codice per ogni lettera in seq, o sottrarre le lettere in seq2.
È necessario un secondo passaggio per verificare che le corrispondenze proposte siano corrette in caso di collisione dell'hash.
fonte
2013-06-08 19:23:14
Con mutato, vuoi dire le lettere possono essere riorganizzate? – jamylak
@jamylak sì, hai ragione.Qualcosa come gli anagrammi, la sequenza in un'altra stringa può essere un anagramma di sequenza nella prima stringa, o viceversa. – Amit
si chiama permutazione – blue