Verständnis Knuth-Morris-Pratt-Algorithmus
Kann mir das jemand erklären? Ich habe schon darüber zu Lesen und es ist immer noch schwer zu Folgen.
text : ababdbaababa
Muster: Abeba
Tabelle für Abeba -1 0 0 1 2.
Ich glaube, ich verstehe, wie die Tabelle aufgebaut ist, aber ich verstehe nicht, wie zu verschieben, nachdem Konflikt aufgetreten ist. Scheint, wie wir nicht einmal verwenden Sie die Tabelle beim schalten?
Wann verwenden wir die Tabelle?
- chekc das aus: jakeboxer.com/blog/2009/12/13/...
Du musst angemeldet sein, um einen Kommentar abzugeben.
die Tabelle wird verwendet, wenn Ihr mismatch Auftritt. Jetzt wenden wir das Muster in Ihren text ein:
Starten Sie passenden text mit Muster und testen Sie, ob das Muster lässt sich in text, beginnend an der ersten position. Vergleichen Sie
text[1]
mitpattern[1]
- und das entpuppt sich als ein match. Sie tun das gleiche fürtext[2]
,text[3]
undtext[4]
.wenn Sie wollen-match -
text[5]
mitpattern[5]
Sie nicht über eine übereinstimmung (d
<>a
). Sie wissen dann, dass Ihre Muster nicht beginnen bei der ersten position. Sie könnten dann starten Sie das passende über und über wieder für position 2, aber das ist nicht effizient. Sie können verwenden Sie die Tabelle nun.Der Fehler aufgetreten bei
pattern[5]
so dass Sie gehen, umtable[5]
2. Das sagt dir, dass Sie beginnen können, Abgleich an der aktuellen position wieder mit 2 bereits erkannten Zeichen. Anstatt start-matching-position 2, können Sie beginnen, an Ihrer bisherigen position (1) +table[5]
(2)=3. In der Tat, Wenn wir unstext[3]
undtext[4]
wir sehen, dass es gleichpattern[1]
undpattern[2]
, respectivily.Die zahlen in der Tabelle sagen Ihnen, wie viele Positionen sind bereits abgestimmt, wenn ein Fehler Auftritt. In diesem Fall werden 2 Zeichen für das nächste Muster wurden bereits abgestimmt. Sie können dann sofort beginnen, für die passende position 3 und skip-position 2 (wie kann das pattern nicht gefunden, beginnend an der position[2]).
Hier habe ich kurz beschrieben computing die Präfix-Funktion und verschiebt sich durch den text hier.
Weitere Informationen: Knuth–Morris–Pratt-string-such-Algorithmus
Verschiebung durch den text :
Szenario 1 - Es gibt einige übereinstimmende Zeichen/s in Muster und Text.
e.g 1: hier gibt es 3 passenden Zeichen.
Erhalten Sie den Wert aus der Tabelle für 3 Zeichen. (index 2, ABC) ich.e 0
Also shift = 3 - 0 ich.e 3
e.g 2: hier gibt es 6 passenden Zeichen.
Den Wert aus der Tabelle für 6 Zeichen. (index 5, ABCDAB) ich.e 2
Daher Verschiebung = 6 - 2 ich.e 4
Szenario 2 - Wenn es keine übereinstimmende Zeichen dann shift um eins.
Gut, das ist ein altes Thema, aber hoffentlich jemand, der sucht diese in der Zukunft wird es sehen. Die Antwort oben ist gut, aber ich war durch ein Beispiel selbst zu sehen, was Los ist genau.
Ersten Teil der Ausstellung stammt aus wiki, der Teil, den ich wirklich wollte, um zu erarbeiten, wie das backtracking-array aufgebaut ist.
Hier geht:
wir arbeiten, durch eine (relativ künstliche) ausführen des Algorithmus, wo
Jederzeit der Algorithmus in einem Zustand bestimmt, der durch zwei Ganzzahlen:
m
bezeichnet die position in S, das ist der Anfang von einem potenziellen match für Wi
den index W bezeichnet den Charakter, die derzeit unter Berücksichtigung.In jedem Schritt vergleichen wir
S[m+i]
mitW[i]
und Voraus, wenn Sie gleich sind. Dies wird dargestellt, zu Beginn des Laufs, wieGehen wir durch den Vergleich von aufeinanderfolgenden Zeichen von W auf "parallel" Zeichen des S, sich von einem zum nächsten, wenn Sie übereinstimmen. Jedoch, im vierten Schritt,
wir bekommen S[3] ist ein Raum und W[3] = 'D', ein Missverhältnis. Eher als Anfang für die Suche wieder auf S[1], wir beachten Sie, dass kein 'A' vorkommt, zwischen den Positionen 0 und 3 in S
außer bei 0; folglich haben überprüft, alle diese Zeichen zuvor, wir wissen, es gibt keine chance, den Beginn einer Partie, wenn wir überprüfen Sie Sie erneut.
Deshalb bewegen wir uns auf das nächste Zeichen, Einstellung m = 4 und i = 0.
Haben wir schnell erhalten Sie eine fast vollständige übereinstimmung "ABCDAB", wenn Sie bei W[6] (S[10]), haben wir wieder eine Diskrepanz. Jedoch, kurz vor dem Ende der aktuellen partiellen
match, wir übergeben eine "AB" - könnte das der Beginn einer neuen übereinstimmen, so müssen wir dies berücksichtigen. Wie wir bereits wissen, dass diese Zeichen entsprechen
die zwei Zeichen vor der aktuellen position brauchen wir Sie nicht überprüfen Sie Sie wieder, wir einfach zurücksetzen m = 8, i = 2 und weiter, passend zu den aktuellen Charakter. So,
nicht nur, dass wir vorher weglassen übereinstimmenden Zeichen von S, aber auch vorher übereinstimmenden Zeichen von W.
Diese Suche nicht sofort, jedoch, als die Muster immer noch nicht die ein Leerzeichen enthalten, so wie in der ersten Studie, die wir zurück an den Anfang von W und beginnen
die Suche auf das nächste Zeichen von S: m = 11, zurückgesetzt i = 0.
Wir mal wieder sofort treffen auf ein match "ABCDAB" aber das nächste Zeichen, 'C', entspricht nicht der endgültige Charakter " D " des Wortes W. Argumentation wie zuvor,
wir setzen m = 15, zu Beginn zwei-Zeichen-string "AB" im Vorfeld der aktuellen position i = 2, und weiterhin die passenden von der aktuellen position.
Dieser Zeit sind wir in der Lage das Spiel, dessen ersten Charakter S[15].
Obigen Beispiel enthält alle Elemente des Algorithmus. Für den moment gehen wir davon aus, die Existenz eines "partial match" T-Tabelle, die nachfolgend beschrieben werden, die
zeigt an, wo wir brauchen, um für den start eines neuen Spiels in dem Fall, dass der aktuelle endet in einem Missverhältnis. Die Einträge von T sind so konstruiert, dass
wenn wir ein match, beginnend bei S[m] nicht, dass beim Vergleich von S[m + - i] W[i], dann die nächste mögliche übereinstimmung wird beginnen bei index m + i - T[i] in S (das ist,
T[i] ist die Menge der "backtracking" wir müssen tun, nach einem mismatch). Dies hat zwei Implikationen: Erstens, T[0] = -1, was bedeutet, dass, falls W[0] ist eine Diskrepanz,
wir können nicht zurück und müssen einfach schauen, dass das nächste Zeichen; und zweitens, obwohl die nächsten möglichen match beginnt bei index m + i - T[i], wie im Beispiel
oben brauchen wir nicht wirklich überprüfen, der T[i] - Zeichen danach, so dass wir weiterhin auf der Suche von W[T[i]].
BACKTRACKING-ARRAY-KONSTRUKTION:
also das backtracking array T[] wir rufen lps[], lasst uns sehen, wie wir das berechnen dieser Kerl
Beispiele:
Für die Muster "AABAACAABAA",
//so-nur durch diese gehen sehr schnell
- Und das macht Total Sinn, wenn man darüber nachdenkt...wenn Sie nicht übereinstimmen, Sie wollen zurück zu gehen, so weit wie Sie können, natürlich, wie weit zurück Sie gehen (das suffix
Teil) ist im wesentlichen das Präfix, da müssen Sie start-matching aus dem ersten Zeichen wieder durch definition. also, wenn dein string aussieht
aaaaaaaaaaaaaaa..b..aaaaaaaaaaaaaaac
und Sie mismatche auf den letzten char c, dann, das Sie wiederverwenden möchtenaaaaaaaaaaaaaaa
als Ihr neues Kopf, finde es nur durchEine Komplette Lösung, die mit Java: