Ich suche nach einem schnellen k-Mismatch-String-Matching-Algorithmus. Bei einer gegebenen Musterfolge P der Länge m und einer Textzeichenfolge T der Länge n benötige ich einen schnellen (linearen Zeit-) Algorithmus, um alle Positionen zu finden, an denen P mit einer Teilzeichenfolge von T mit höchstens k Fehlpaarungen übereinstimmt. Dies unterscheidet sich vom Problem der k-Unterschiede (Bearbeitungsabstand). Eine Nichtübereinstimmung impliziert, dass der Teilstring und das Muster an höchstens k Positionen einen anderen Buchstaben haben. Ich benötige wirklich nur k = 1 (höchstens 1 Fehlanpassung), daher reicht auch ein schneller Algorithmus für den speziellen Fall von k = 1 aus. Die Alphabetgröße beträgt 26 (Groß- und Kleinschreibung wird nicht berücksichtigt, daher sollte der Platzbedarf mit der Größe des Alphabets nicht zu schnell wachsen (z. B. nimmt der FAAST-Algorithmus, glaube ich, in der Größe des Alphabets exponentiell Platz ein, und so weiter) ist nur für Protein- und Gensequenzen geeignet).
Ein auf dynamischer Programmierung basierender Ansatz ist im schlimmsten Fall O (mn), was zu langsam ist. Ich glaube, dass es dafür Modifikationen des Boyer-Moore-Algorithmus gibt, aber ich bin nicht in der Lage, solche Papiere in die Hände zu bekommen. Ich habe kein Abonnement für den Zugriff auf wissenschaftliche Zeitschriften oder Veröffentlichungen, daher müssen alle Referenzen gemeinfrei sein.
Ich würde mich sehr über Hinweise oder Verweise auf frei verfügbare Dokumente oder den Algorithmus selbst für dieses Problem freuen.
Antworten:
Für dieses Problem können Suffix-Arrays verwendet werden. Sie enthalten die Startpositionen jedes Suffixes der Zeichenfolge, sortiert in lexikografischer Reihenfolge. Obwohl sie naiv in -Komplexität konstruiert werden können, gibt es Methoden, um sie in Θ ( n ) -Komplexität zu konstruieren . Siehe zum Beispiel dies und das . Nennen wir dieses Suffix-Array SA.O ( n logn ) Θ ( n )
Sobald das Suffix-Array erstellt wurde, müssen wir ein LCP-Array (Longest Common Prefix) für das Suffix-Array erstellen. Das LCP-Array speichert die Länge des längsten gemeinsamen Präfixes zwischen zwei aufeinanderfolgenden Präfixen im Suffix-Array (lexikografische aufeinanderfolgende Suffixe). Somit enthält LCP [i] die Länge des längsten gemeinsamen Präfixes zwischen SA [i] und SA [i + 1]. Dieses Array kann auch in linearer Zeit erstellt werden: siehe hier , hier und hier für einige gute Referenzen.
quelle
Die Idee ähnelt dem Rabin-Karp-Rolling-Hash- Algorithmus für exakte Teilstring-Übereinstimmungen.
Ich gehe davon aus (Vorbehalt: Ich habe es nicht selbst ausprobiert), dass dies in der Praxis wahrscheinlich schneller und möglicherweise einfacher zu codieren / zu warten ist als die Verwendung eines auf Suffixbäumen basierenden Ansatzes.
quelle