Ist einer von ihnen bei n Zeichenfolgen ein Teilstring eines anderen?

9

Angenommen, wir erhalten eine Sammlung von Zeichenfolgen, . Ich würde gerne wissen, ob eine dieser Zeichenfolgen eine Teilzeichenfolge einer anderen Zeichenfolge in der Sammlung ist. Mit anderen Worten, ich möchte einen Algorithmus für die folgende Aufgabe:S 1 , , S nnS1,,Sn

Eingabe:S1,,Sn

Ausgabe: so dass eine von und , oder Keine, wenn kein solches existiertS i S j i j i , ji,jSiSjiji,j

Gibt es dafür einen effizienten Algorithmus?

Wenn wir "Teilzeichenfolge" durch "Präfix" ersetzen, gibt es einen effizienten Algorithmus (sortieren Sie die Zeichenfolgen und führen Sie dann einen linearen Scan durch, um benachbarte Zeichenfolgen zu vergleichen; durch Sortieren wird sichergestellt, dass Teilzeichenfolgen benachbart sind). Es scheint jedoch schwieriger zu testen, ob eine Zeichenfolge eine Teilzeichenfolge einer anderen Zeichenfolge ist. Ein naiver Algorithmus besteht darin, über alle Paare zu iterieren , dies erfordert jedoch -Substring-Tests. Gibt es einen effizienteren Algorithmus?Θ ( n 2 )i,jΘ(n2)

Ich denke, wir könnten dies "All-Pair-Teilstringtest" oder so etwas nennen.

Mein letztendliches Ziel ist es, die Sammlung so zu beschneiden, dass kein String ein Teilstring eines anderen ist, indem jeder entfernt wird, der ein Teilstring von etwas anderem in der Sammlung ist.

DW
quelle
Hinweis: Suffix-Array.
Pseudonym
Als Randnotiz ist nicht korrekt, wenn Sie Teilzeichenfolgen entfernen, sobald Sie sie finden. Es wird weniger sein. Außerdem sollten Sie nach Länge sortieren, da eine längere Zeichenfolge nicht in einer kürzeren Zeichenfolge angezeigt werden kann. Wieder ist hier falsch. Θ ( n 2 )Θ(n2)Θ(n2)
Alexis Wilke
@AlexisWilke, ist richtig: Das ist die Anzahl der Teilstringtests im schlimmsten Fall (im schlimmsten Fall ist kein String ein Teilstring eines anderen). Wenn Sie nach Länge sortieren, erhalten Sie nur den Faktor zwei, was die Asymptotik nicht beeinflusst. Θ(n2)
DW

Antworten:

6

Sie können einen Suffixbaum in linearer Zeit erstellen und prüfen, ob ein innerer Knoten vorhanden ist, der einer vollständigen Zeichenfolge entspricht (konstante Zeit pro Knoten).

Nehmen wir genauer an, wir erhalten die Zeichenfolgen .s1,,snΣ

  1. Erstellen Sie einen (verallgemeinerten) Suffixbaum aus mit paarweise unterschiedlichen Terminalmarkierungen . n $ 1 , , $ nΣs1$1,s2$2,,sn$nn$1,,$nΣ

    Mit dem Ukkonen-Algorithmus kann dies in linearer Zeit erfolgen. linear in der Summe aller Saitenlängen.

  2. (i,j)si[j..|si|]sin(i,0)

    Dies erfordert eine lineare Zeit in der Baumgröße, die selbst in der Eingabegröße linear ist.

  3. (i,0)$i(i,0)

    Dies dauert wieder lineare Zeit.

Die unterschiedlichen Endmarkierungen sind nicht wirklich notwendig; Eine einzige, die zum Beenden aller Zeichenfolgen verwendet wird, ist völlig ausreichend, solange Sie mehrere Beschriftungen pro Blatt zulassen.

Raphael
quelle