Ich interessiere mich für Versuche und DAWGs (Direct Acyclic Word Graph) und habe viel darüber gelesen, aber ich verstehe nicht, wie die Ausgabe-Trie oder DAWG-Datei aussehen soll.
- Sollte ein Versuch ein Objekt verschachtelter Wörterbücher sein? Wo ist jeder Buchstabe in Buchstaben unterteilt und so weiter?
- Wäre eine Suche in einem solchen Wörterbuch schnell, wenn 100.000 oder 500.000 Einträge vorhanden wären?
- Wie implementiere ich Wortblöcke, die aus mehr als einem durch
-
oder Leerzeichen getrennten Wort bestehen ? - Wie verknüpfe ich das Präfix oder Suffix eines Wortes mit einem anderen Teil der Struktur? (für DAWG)
Ich möchte die beste Ausgabestruktur verstehen , um herauszufinden, wie man eine erstellt und verwendet.
Ich würde mich auch freuen, was die Ausgabe einer DAWG zusammen mit Trie sein sollte .
Ich möchte keine grafischen Darstellungen mit miteinander verknüpften Blasen sehen, ich möchte das Ausgabeobjekt kennen, sobald eine Reihe von Wörtern in Versuche oder DAWGs umgewandelt wurde.
Antworten:
Abwickeln ist im Wesentlichen richtig, dass es viele verschiedene Möglichkeiten gibt, einen Versuch zu implementieren; und für einen großen, skalierbaren Versuch können verschachtelte Wörterbücher umständlich werden - oder zumindest platzsparend. Aber da Sie gerade erst anfangen, denke ich, dass dies der einfachste Ansatz ist. Sie könnten eine einfache
trie
in nur wenigen Zeilen codieren . Zunächst eine Funktion zum Konstruieren des Versuchs:Wenn Sie nicht vertraut sind
setdefault
, wird einfach ein Schlüssel im Wörterbuch nachgeschlagen (hierletter
oder_end
). Wenn der Schlüssel vorhanden ist, wird der zugehörige Wert zurückgegeben. Wenn nicht, weist es diesem Schlüssel einen Standardwert zu und gibt den Wert ({}
oder_end
) zurück. (Es ist wie eine Version davonget
, die auch das Wörterbuch aktualisiert.)Als nächstes eine Funktion zum Testen, ob das Wort im Versuch ist:
Ich überlasse Ihnen das Einfügen und Entfernen als Übung.
Natürlich wäre der Vorschlag von Unwind nicht viel schwieriger. Es könnte einen leichten Geschwindigkeitsnachteil geben, wenn das Finden des richtigen Unterknotens eine lineare Suche erfordern würde. Die Suche wäre jedoch auf die Anzahl der möglichen Zeichen beschränkt - 27, wenn wir einschließen
_end
. Es gibt auch nichts zu gewinnen, wenn Sie eine umfangreiche Liste von Knoten erstellen und über einen Index darauf zugreifen, wie er vorschlägt. Sie können die Listen auch einfach verschachteln.Abschließend möchte ich hinzufügen, dass das Erstellen eines gerichteten azyklischen Wortgraphen (DAWG) etwas komplexer wäre, da Sie Situationen erkennen müssen, in denen Ihr aktuelles Wort ein Suffix mit einem anderen Wort in der Struktur teilt. Tatsächlich kann dies ziemlich komplex werden, je nachdem, wie Sie die DAWG strukturieren möchten! Möglicherweise müssen Sie einige Dinge über die Levenshtein- Entfernung lernen , um es richtig zu machen.
quelle
dict.setdefault()
(es ist nicht ausgelastet und bei weitem nicht bekannt genug), zum Teil, weil es dazu beiträgt, Fehler zu vermeiden, die mit a zu einfach zu erstellen sinddefaultdict
(wo SieKeyError
bei der Indizierung keine für nicht vorhandene Schlüssel erhalten würden). Das einzige, was es jetzt für den Produktionscode verwendbar machen würde, ist die Verwendung von_end = object()
:-)Schau dir das an:
https://github.com/kmike/marisa-trie
Hier ist ein Blog-Beitrag eines Unternehmens, das Marisa Trie erfolgreich einsetzt:
https://www.repustate.com/blog/sharing-large-data-structure-across-processes-python/
Es gibt auch einige reine Python-Implementierungen. Wenn Sie sich jedoch nicht auf einer eingeschränkten Plattform befinden, möchten Sie die oben genannte C ++ - unterstützte Implementierung verwenden, um die beste Leistung zu erzielen:
quelle
Hier ist eine Liste von Python-Paketen, die Trie implementieren:
quelle
Geändert von
senderle
der Methode (oben). Ich fand, dass Pythonsdefaultdict
ideal zum Erstellen eines Trie- oder Präfixbaums ist.quelle
Es gibt kein "sollte"; Es liegt an dir. Verschiedene Implementierungen weisen unterschiedliche Leistungsmerkmale auf, benötigen unterschiedliche Zeit, um sie zu implementieren, zu verstehen und richtig zu machen. Dies ist meiner Meinung nach typisch für die gesamte Softwareentwicklung.
Ich würde wahrscheinlich zuerst versuchen, eine globale Liste aller bisher erstellten Knoten zu erstellen und die untergeordneten Zeiger in jedem Knoten als Liste von Indizes in der globalen Liste darzustellen. Ein Wörterbuch zu haben, das nur die Verknüpfung des Kindes darstellt, fühlt sich für mich zu schwer an.
quelle
Wenn Sie möchten, dass ein TRIE als Python-Klasse implementiert wird, habe ich Folgendes geschrieben, nachdem ich darüber gelesen habe:
quelle
Diese Version verwendet die Rekursion
Ausgabe:
quelle
Definiere Trie:
Erstellen Sie Trie:
Sieh nach oben:
Prüfung:
quelle
True
nur für ein ganzes Wort zurückgegeben, nicht jedoch für das Präfix, für die Änderung des Präfixesreturn '_end' in curr
inreturn True
aus
quelle
Python-Klasse für Trie
Die Datenstruktur kann verwendet werden, um Daten zu speichern,
O(L)
wobei L die Länge der Zeichenfolge ist, sodass zum Einfügen von N Zeichenfolgen die zeitliche KomplexitätO(NL)
der Zeichenfolge durchsucht werden kannO(L)
nur zum Löschen .Kann von https://github.com/Parikshit22/pytrie.git geklont werden
Code Oputpt
Wahr
Falsch
[ 'Minakshi', 'Minhaj']
7
Minakshi
minhajsir
pari
parikshit
shubh
shubham
Shubhi
quelle