Wie überprüfe ich effizient, ob eine Zeichenfolge mit einer Teilzeichenfolge in einer Sammlung übereinstimmt?

7

Ich habe eine Sammlung von Teilzeichenfolgen

"this" "is" "a" "antelope"

Ich muss mir eine bestimmte Zeichenfolge ansehen und die Frage beantworten, ob eine der angegebenen Teilzeichenfolgen in dieser Zeichenfolge enthalten ist.

So könnte meine Eingabezeichenfolge sein

"issue"

Was eine Übereinstimmung wäre, weil "ist" eine Teilzeichenfolge von "Problem" ist

Bei meinem ersten Versuch habe ich meine Sammlung von Teilzeichenfolgen fälschlicherweise in einen Versuch verwandelt. Das brachte mich nicht schnell voran, als es auf die Umkehrung antwortete: "Ist die Eingabezeichenfolge eine Teilzeichenfolge der angegebenen Sammlung?".

Gibt es einen Algorithmus oder eine Datenstruktur, in die ich meine Sammlung umwandeln kann, um diese Frage effizient zu beantworten? Ich meine, ich könnte die einfache Brute-Force-Methode "Überprüfen Sie die Eingabe gegen jeden Teilstring" durchführen, aber es scheint, als gäbe es einen besseren Weg.

In meinem Beispiel würde ich erwarten, dass "Antilope" niemals überprüft wird, da "a" jeden Fall abdeckt, den Antilope würde. Ich kann sogar erwarten, dass "is" "this" entfernen würde, da jeder Fall, in dem "this" eine Übereinstimmung finden würde, "is" auch würde. Es scheint also, als würde das Eliminieren längerer Teilzeichenfolgen durch kürzere zu einer besseren Leistung führen.

Ich streife ... Was sollte ich mir ansehen?

Cogman
quelle
Haben Sie sich mit Standard-Suchalgorithmen für Teilzeichenfolgen (wie Boyer-Moore) befasst? Sie können nacheinander nach jedem Teilstring in Ihrer Sammlung suchen, bis Sie eine Übereinstimmung erreichen.
James Evans
1
@ dirk5959 Die sequentielle Verwendung eines Single-String-Matching-Algorithmus wäre sehr ineffizient. Wenn der zu durchsuchende String beispielsweise kein "a" enthält, enthält er sicherlich kein "banana", aber Sie würden trotzdem danach suchen.
David Richerby
Hinweis: Suffixbäume.
Raphael

Antworten:

6

Ich denke, der Aho-Corasick- Algorithmus ist hier die beste Wahl. Der Algorithmus wurde entwickelt, um das Mengenanpassungsproblem (im Wesentlichen das von Ihnen definierte) zu lösen, bei dem Sie bestimmen möchten, welche Elemente einer Menge von Teilzeichenfolgen L in einer längeren Zeichenfolge S enthalten sind.

Es läuft in der Zeit , wobei(die Gesamtlänge der kombinierten Teilketten in ), ist die Länge S, und ist die Anzahl von Übereinstimmungen von in .O(n+m+z)n=lL|l|LmzLS

James Evans
quelle