Algorithmus zu finden, der am meisten common substrings in einem string
Gibt es Algorithmus, der verwendet werden kann, finden die häufigsten Sätze (oder Zeichenketten) in einem string? Zum Beispiel die folgende Zeichenfolge wäre das "Hallo Welt" als gemeinsame zwei-Wort-Satz:
"hello world this is hello world. hello world repeats three times in this string!"
In der Zeichenfolge oben, die häufigste string (nachdem die leere Zeichenfolge Zeichen, die wiederholt eine unendliche Anzahl von Zeiten) wäre das Leerzeichen .
Gibt es eine Möglichkeit um eine Liste von gemeinsamen Teilzeichenfolgen in dieser Zeichenfolge, aus den gängigsten zu den am wenigsten verwendeten?
- Definieren, was meinst du mit phrase, die substring -
"l"
ist häufiger dann"hello world"
. Und natürlich"hello"
ist mindestens so Häufig wie"hello world"
. - Ich meinte wirklich "die meisten common substring in einem string".
- Dann werden die meisten common substring die leere Zeichenkette (wiederholt sich unendliche Male). Die Sekunde danach ist das häufigste Zeichen. Finden es kann leicht getan werden mit einem Histogramm in
O(n)
. - Ich glaube nicht, dass Sie wirklich verstanden, amit ' s Kommentar. Sie schreiben, "In dem string vor, der häufigste string wäre
hello world
"; aber der Teilstringhello world
tritt nur dreimal, in der Erwägung, dass die substring -l
tritt neun mal. (Undis
vier mal vorkommt. Und" "
tritt fünfzehn mal.) - Nach dem Auffinden der häufigste Charakter, würde ich versuchen, die häufigsten zwei-Zeichen-strings, die begann mit jedem Charakter. Dann würde ich versuchen, die häufigsten drei-Zeichen-strings, die begann mit den gängigsten zwei-Zeichen-strings, und so weiter.
- Ich reparierte den Fehler - vielen Dank für die Klarstellung!
- "" ist das am meisten common substring, es wiederholt sich unendliche Male.
- en.wikipedia.org/wiki/Suffix_tree#Functionality und en.wikipedia.org/wiki/Suffix_array wenn Sie denken, große Streicher bei 10000 oder 100000 Maßstab.
- "Hallo Welt" - Antworten deutet darauf hin, dass Sie wollen, finden Sie die längste doppelten Teilstring
- dann bedeutet es, dass die längste Zeichenkette, die angezeigt wird, zweimal? Was ist mit diesem Beispiel
"AAAAAAAAAAAAAAAAAAAAAAA hello world AAAAAAAAAAAAAAAAAAAAAAA hello world hello world"
. Hier die am häufigsten vorkommenden Teilstring 'A' und den längsten substring (Auftritt mindestens zweimal) ist"AAAAAAAAAAAAAAAAAAAAAAA"
. Was muss meine Funktion zurückgeben? - es gibt
"AA..."
das ist korrekt wenn die Antwort auf die erste Frage ist"hello world"
und nicht"l"
das ist das gemeinsame Teilzeichenfolge nach" "
.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies ist als Aufgabe ähnlich der Nussinov-Algorithmus ist, und sogar noch einfacher, da wir nicht zulassen, dass irgendwelche Lücken, Einfügungen oder Unterschiede in der Ausrichtung.
Für die Schnur mit der Länge N, definieren Sie eine
F[-1 .. N, -1 .. N]
Tabelle und füllen Sie mit den folgenden Regeln:Beispielsweise für B A O B A B:
Dieser läuft in
O(n^2)
Zeit. Die größten Werte in der Tabelle nun auf den end-Positionen der längste self-matching subquences (ich - das Ende einer Begebenheit, j - anderen). Am Anfang, das array wird angenommen, dass null initialisiert werden. Ich habe Hinzugefügt-Bedingung ausschließen, die Diagonale ist die längste, aber wohl nicht interessant-selbst-übereinstimmen.Denken mehr, diese Tabelle ist symmetrisch über die Diagonale, so ist es genug, um zu berechnen, nur die Hälfte. Auch das array mit null initialisiert, so dass die Zuweisung von null ist redundant. Bleibt
Kürzer, aber möglicherweise schwieriger zu verstehen. Die berechnete Tabelle enthält alle Spiele, kurze und lange. Sie können weitere Filterung, wie Sie benötigen.
Im nächsten Schritt müssen Sie sich zu erholen Zeichenfolgen, die aus dem nicht-null-Zellen, die nach oben und nach Links von der Diagonale. Während dieser Schritt ist auch trivial, um einige hashmap, um die Anzahl der selbst-ähnlichkeit entspricht, für die gleiche Zeichenfolge. Mit normalen string und normale minimale Länge nur kleine Anzahl von Zellen in einer Tabelle verarbeitet werden, wird durch diese Karte.
Ich denke, dass mit hashmap direkt tatsächlich erfordert O(n^3), wie die key-strings an das Ende des Zugangs verglichen werden müssen, irgendwie für Gleichstellung. Dieser Vergleich ist wahrscheinlich O(n).
Python. Dies ist etwas quick and dirty, mit den Daten Strukturen zu tun, die meisten heben.
Den Zähler Datenstruktur ist eine hash-backed Wörterbuch-ausgelegt für das zählen, wie viele Male haben Sie etwas gesehen. Hinzufügen, um einen nicht vorhandenen Schlüssel erstellen wird es, beim abrufen eine nicht vorhandene Schlüssel geben Sie null anstelle von ein Fehler. So alle Sie tun müssen ist, Durchlaufen alle Teilstrings.
for start in range(len(text) - length)
und töten dieif
.accumulator.most_common()
nur pseudo-code, und das ist vielleicht nicht die schönste Lösung, aber würde ich lösen wie diese:
Wo die map enthalten kann ein Schlüssel-Wert-Paare, wie in der Java-HashMap.
Perl,
O(n²)
Lösungzeigt die 10 besten Wertungen der meisten gemeinsamen sub-strings (im Falle eines Unentschieden, zeigen die längste Kette von Worten erste). Ändern
$display
zu1
zu haben, nur das Ergebnis.Es gibt
n(n+1)/2
Iterationen.Da für jeden substring einen String der Länge >= 2 der text enthält mindestens einen substring der Länge 2 mindestens so oft, brauchen wir nur zu untersuchen, Teilstrings der Länge 2.