Levenshtein-Wandler akzeptieren einen Abfragebegriff und geben alle Begriffe in einem Wörterbuch zurück, die innerhalb von n Rechtschreibfehlern von ihm entfernt sind. Sie stellen eine hocheffiziente (räumlich und zeitlich) Klasse von Rechtschreibkorrekturen dar, die sehr gut funktionieren, wenn Sie beim Unterbreiten von Vorschlägen keinen Kontext benötigen. Vergessen Sie die Durchführung eines linearen Scans Ihres Wörterbuchs, um alle Begriffe zu finden, die der Suchanfrage des Benutzers ausreichend nahe kommen. Mit einer quadratischen Implementierung der Levenshtein-Distanz oder der Damerau-Levenshtein-Distanz finden diese Babys alle Begriffe aus Ihrem Wörterbuch in linearer Zeit die Länge des Abfragebegriffs (nicht von der Größe des Wörterbuchs, sondern von der Länge des Abfragebegriffs).
Wenn Sie Kontext benötigen, nehmen Sie die vom Wandler generierten Kandidaten als Ausgangspunkt und fügen Sie sie in das Modell ein, das Sie für den Kontext verwenden (z. B. indem Sie die Sequenz von Begriffen auswählen, die mit der größten Wahrscheinlichkeit zusammen auftauchen).
Für eine kurze Demonstration besuchen Sie bitte die Github-Seite hier. Es gibt auch eine Befehlszeilenschnittstelle, libevenshtein-java-cli. Informationen zum Erwerb und zur Nutzung finden Sie in der Datei README.md.
Die Bibliothek ist derzeit in Java, CoffeeScript und JavaScript geschrieben, aber ich werde sie bald in andere Sprachen portieren. Wenn Sie eine bestimmte Sprache haben, in der Sie es sehen möchten, oder ein Paketverwaltungssystem, in dem Sie es bereitstellen möchten, lassen Sie es mich wissen.
Zweig | Beschreibung |
---|---|
Master | Neueste Entwicklungsquelle |
freigeben | Neueste Versionsquelle |
Release-3.x | Neueste Release-Quelle für Version 3.x |
Release-2.x | Neueste Release-Quelle für Version 2.x |
Probleme werden auf waffle.io verwaltet. Unten finden Sie eine Grafik zur Rate, mit der ich sie geschlossen habe.
Bitte besuchen Sie Bountysource, um Ihre Unterstützung für aktuelle Probleme zuzusagen.
Bei der Dokumentation haben Sie mehrere Möglichkeiten:
Wiki
Javadoc
Quellcode
libevenshtein wurde für Java ≥ 1.8 entwickelt. Es funktioniert nicht mit früheren Versionen.
Fügen Sie eine Maven-Abhängigkeit zu Artifactory hinzu. In einem Gradle-Projekt würden Sie Ihre repositories
beispielsweise wie folgt ändern:
Repositories { Maven { URL „https://oss.jfrog.org/artifactory/oss-release-local“ } }
Fügen Sie eine Maven-Abhängigkeit von einem der folgenden Elemente hinzu:
Maven Central
JCenter
Bintray
<Abhängigkeit> <groupId>com.github.universal-automata</groupId> <artifactId>liblevenshtein</artifactId> <version>3.0.0</version> </Abhängigkeit>
'com.github.universal-automata:liblevenshtein:jar:3.0.0'
<dependency org="com.github.universal-automata" name="liblevenshtein" rev="3.0.0" />
@Trauben( @Grab(group='com.github.universal-automata', module='liblevenshtein', version='3.0.0') )
kompilieren Sie 'com.github.universal-automata:liblevenshtein:3.0.0'
Bibliotheksabhängigkeiten += "com.github.universal-automata" % "liblevenshtein" % "3.0.0"
[com.github.universal-automata/liblevenshtein „3.0.0“]
% git clone --progress [email protected]:universal-automata/liblevenshtein-java.git Cloning into 'liblevenshtein-java'... remote: Counting objects: 8117, done. remote: Compressing objects: 100% (472/472), done. remote: Total 8117 (delta 352), reused 0 (delta 0), pack-reused 7619 Receiving objects: 100% (8117/8117), 5.52 MiB | 289.00 KiB/s, done. Resolving deltas: 100% (5366/5366), done. Checking connectivity... done. % cd liblevenshtein-java % git pull --progress Already up-to-date. % git fetch --progress --tags % git checkout --progress 3.0.0 Note: checking out '3.0.0'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b <new-branch-name> HEAD is now at 4f0f172... pushd and popd silently % git submodule init % git submodule update
Nehmen wir an, Sie haben den folgenden Inhalt in einer Nur-Text-Datei mit dem Namen „top-20-most-common-english-words.txt“ (beachten Sie, dass die Datei einen Begriff pro Zeile enthält):
the be to of and a in that have I it for not on with he as you do at
Im Folgenden finden Sie eine Möglichkeit, den Inhalt abzufragen:
java.io.InputStream importieren; java.io.OutputStream importieren; java.nio.file.Files importieren; java.nio.file.Path importieren; java.nio.file.Paths importieren; com.github.liblevenshtein.collection importieren. dictionary.SortedDawg;import com.github.liblevenshtein.serialization.PlainTextSerializer;import com.github.liblevenshtein.serialization.ProtobufSerializer;import com.github.liblevenshtein.serialization.Serializer;import com.github.liblevenshtein.transducer.Algorithm;import com.github.liblevenshtein.transducer.Candidate;import com.github.liblevenshtein.transducer.ITransducer;import com.github.liblevenshtein.transducer.factory.TransducerBuilder;// ...final SortedDawg dictionary;final Path dictionaryPath = Paths.get("/path/to/top-20-most-common-english-words.txt");try (final InputStream stream = Files.newInputStream(dictionaryPath)) { // Der PlainTextSerializer-Konstruktor akzeptiert eine optionale boolesche Angabe // ob das Wörterbuch bereits lexikografisch aufsteigend sortiert ist // Befehl. Wenn es sortiert ist, wird die Konstruktion durch die Übergabe von true optimiert // des Wörterbuchs; Sie können false übergeben, unabhängig davon, ob das Wörterbuch sortiert ist oder // nicht (dies ist das standardmäßige und sicherste Verhalten, wenn Sie nicht wissen, ob die // Wörterbuch ist sortiert). final Serializer serializer = new PlainTextSerializer(false); dictionary = serializer.deserialize(SortedDawg.class, stream); }final ITransducer<Candidate> Transducer = new TransducerBuilder() .dictionary(Wörterbuch) .algorithm(Algorithmus.TRANSPOSITION) .defaultMaxDistance(2) .includeDistance(true) .build();for (final String queryTerm : new String[] {"foo", "bar"}) { System.out.println("+---------------- -------------------------------------------------- -------------"); System.out.printf("| Rechtschreibkandidaten für den Abfragebegriff: "%s"%n", queryTerm); System.out.println("+---------------------------- -------------------------------------"); for (endgültiger Kandidat: Transducer.transduce(queryTerm)) {System.out.printf("| d("%s", "%s") = [%d]%n", queryTerm, Candidate.term() , Candidate.distance()); } }// +------------------------------- ---------------------------------// | Rechtschreibkandidaten für den Suchbegriff: „foo“// +-------------------------------------- -----------------------------------------// | d("foo", "do") = [2]// | d("foo", "of") = [2]// | d("foo", "on") = [2]// | d("foo", "to") = [2]// | d("foo", "for") = [1]// | d("foo", "not") = [2]// | d("foo", "you") = [2]// +--------------------------------- ----------------------------------------------// | Rechtschreibkandidaten für den Suchbegriff: „bar“// +-------------------------------------- -----------------------------------------// | d("bar", "a") = [2]// | d("bar", "as") = [2]// | d("bar", "at") = [2]// | d("bar", "be") = [2]// | d("bar", "for") = [2]// ...
Wenn Sie Ihr Wörterbuch in ein später leicht lesbares Format serialisieren möchten, gehen Sie wie folgt vor:
final Path serializedDictionaryPath = Paths.get("/path/to/top-20-most-common-english-words.protobuf.bytes");try (final OutputStream stream = Files.newOutputStream(serializedDictionaryPath)) { final Serializer serializer = neuer ProtobufSerializer(); serializer.serialize(dictionary, stream); }
Anschließend können Sie das Wörterbuch später auf die gleiche Weise lesen, wie Sie die Klartextversion lesen:
final SortedDawg deserializedDictionary;try (final InputStream stream = Files.newInputStream(serializedDictionaryPath)) { final Serializer serializer = new ProtobufSerializer(); deserializedDictionary = serializer.deserialize(SortedDawg.class, stream); }
Die Serialisierung ist nicht auf Wörterbücher beschränkt, Sie können auch Transducer (de)serialisieren.
Weitere Informationen finden Sie im Wiki.
Diese Bibliothek basiert weitgehend auf der Arbeit von Stoyan Mihov, Klaus Schulz und Petar Nikolaev Mitankin: Fast String Correction with Levenshtein-Automata. Weitere Informationen finden Sie im Wiki.
liblevenshtein-java wird verwaltet von@dylon ([email protected])