16

Gemäß dem wikipedia entry Rabin-Karp String-Matching-Algorithmus kann es verwendet werden, um mehrere verschiedene Muster in einer Zeichenfolge gleichzeitig zu suchen, während die lineare Komplexität beibehalten wird. Es ist klar, dass dies leicht gemacht wird, wenn alle Muster die gleiche Länge haben, aber ich bekomme immer noch nicht, wie wir O (n) -Komplexität bewahren können, wenn wir gleichzeitig nach Mustern mit unterschiedlicher Länge suchen. Kann jemand bitte etwas Licht darauf werfen?Verwenden von Rabin-Karp zum Suchen nach mehreren Mustern in einer Zeichenfolge

Edit (Dezember 2011):

Wikipedia-Artikel wurde seit aktualisiert und keine Ansprüche mehr mehrere Muster unterschiedlicher Länge in O (n) zu entsprechen.

+0

Es ist nicht die genaue Antwort, da sie nur mit der Suche nach einer Zeichenfolge zu einer Zeit beschäftigt, nicht mehrere, aber es gibt möglicherweise nützliche Informationen (unter der Überschrift "Karp Rabin"), die Ihnen helfen können: http://www-igm.univ-mlv.fr/~lecroq/string/index.html –

+0

Die Wikipedia Artikel behauptet, es kann mehrere Muster in O (n) Zeit finden. – MAK

Antwort

5

Ich bin mir nicht sicher, ob dies die richtige Antwort ist, aber trotzdem:

Während den Hash-Wert konstruieren, können wir für eine Übereinstimmung in dem Satz von String-Hashes überprüfen. Aka, der aktuelle Hash-Wert. Die Hash-Funktion/Code wird normalerweise als eine Schleife implementiert und innerhalb dieser Schleife können wir unsere schnelle Suche einfügen.

Natürlich müssen wir m auswählen, um die maximale Stringlänge aus der Menge der Strings zu haben.

Update: aus Wikipedia,

[...] 
for i from 1 to n-m+1 
     if hs ∈ hsubs 
      if s[i..i+m-1] = a substring with hash hs 
       return i 
     hs := hash(s[i+1..i+m]) // <---- calculating current hash 
[...] 

Wir berechnen aktuellen Hash in m Schritten. Für jeden Schritt gibt es einen temporären Hash-Wert, den wir in der Menge der Hashes nachschlagen können (O (1) -Komplexität). Alle Hashes haben die gleiche Größe, dh 32 Bit.

Update 2: eine abgeschrieben (Durchschnitt) O (n) Zeit Komplexität?

Oben habe ich gesagt, dass m die maximale Stringlänge haben muss. Es stellt sich heraus, dass wir das Gegenteil ausnutzen können.
Mit hashing for shifting substring search und einer festen m Größe können wir O (n) Komplexität erreichen.

Wenn wir Strings variabler Länge haben, können wir m auf die minimale Stringlänge setzen. Außerdem ordnen wir in der Menge der Hashes keinen Hash mit der gesamten Zeichenfolge zu, sondern mit den ersten m-Zeichen davon.
Jetzt, während wir den Text suchen, überprüfen wir, ob der aktuelle Hash im Hash-Set ist und untersuchen die zugehörigen Zeichenfolgen für eine Übereinstimmung.

Diese Technik erhöht die Fehlalarme, hat aber im Durchschnitt eine (n) Zeitkomplexität.

+0

Könnten Sie bitte ausarbeiten? Soweit ich das verstehen kann, schlagen Sie vor, mehrere Hashes (einen für jede Musterlänge) zu behalten und diese zu verwenden, um eine Hashtabelle/BST abzufragen. Rechnet man jedoch nicht mehr als eine konstante Zahl, wenn Hashes für jede Iteration die Komplexität mehr als linear machen? – MAK

+0

@MAK, siehe mein Update. –

+0

Danke für die Erklärung. Aber das ist genau die Quelle meiner Verwirrung. Wenn wir den aktuellen Hash-Wert in m Schritten berechnen, ist unsere Gesamtkomplexität nicht mehr linear. Es wird O (n * m) (n ist die Länge des Strings, m ist die Länge des längsten Musters). – MAK

0

Es ist, weil die Hash-Werte der Teilstrings mathematisch verwandt sind. Berechnen des Hash H (S, J) (der Hash-Codierung der Zeichen aus der j-ten Position der Zeichenkette beginnen S) hat O (m) Zeit auf einem String der Länge m. Aber sobald Sie das haben, kann die Berechnung H (S, j + 1) in konstanter Zeit erfolgen, weil H (S, j + 1) kann als eine Funktion von H (S, j) ausgedrückt werden .

O (m) + 0 (1) => 0 (m), d.h. lineare Zeit.

Here's a link wo dies näher beschrieben wird (siehe zum Beispiel den Abschnitt „Was macht Rabin-Karp schnell?“)

+0

Ich verstehe, warum Rabin-Karp schnell ist. Ich habe früher schon einzelne Muster in einer Zeichenfolge gefunden. Ich versuche herauszufinden, wie man mehrere Muster in einer Zeichenkette gleichzeitig in O (n) Zeit finden kann (im Gegensatz zu O (n * k), wenn man nacheinander nach k Mustern sucht). – MAK

+0

@MAK: Entschuldigung, ich habe deine Frage missverstanden. Ist das nicht die Antwort am Ende des Wikipedia-Artikels? "Im Gegensatz dazu kann die obige Rabin-Karp-Variante alle k Muster in O (n + k) -Zeit in Erwartung finden, weil eine Hash-Tabelle prüft, ob ein Teilzeichenfolge-Hash gleich einem der Muster-Hashes in O (1) -Zeit ist." Erstellen des Hash ist O (k). Suchen nach einer Übereinstimmung in einer Hash-Tabelle ist eine O (1) -Operation. Wenn Sie ein Match haben, gewinnen Sie. –

Verwandte Themen