Mit einem binären Suchbaum als Rechtschreibprüfung

stimmen
4

den meisten efficent Weg fragen, einen binären Suchbaum in eine Rechtschreibprüfung zu machen, in etwa 1000 Wort-Wörterbuch-Datei durch das Lese und dann mit ihm ein anderen Dokument überprüfen, die ein paar Absätze sagen hat.

Veröffentlicht am 05/12/2008 um 03:05
quelle vom benutzer
In anderen Sprachen...                            


8 antworten

stimmen
8

ein ternärer Baum Trie wäre effizienter

Beantwortet am 05/12/2008 um 03:22
quelle vom benutzer

stimmen
0

Wenn Sie ein Auto-vorschlagen / Präfixsuche auch tun müssen, dann ein PATRICIA-Baum oder Radix Baum ist einen Blick wert.

Beantwortet am 05/12/2008 um 03:26
quelle vom benutzer

stimmen
0

Mit dem Beispiel, das Sie gegeben hat, ist die Leistung wahrscheinlich irrelevant sein, da auf einem PC die ganze Operation in etwa 1% der Zeit in Anspruch nehmen wird der Benutzer nimmt das erste Ergebnis lesen Sie zeigen, sofern Sie nicht über einen völlig dumm Algorithmus verwenden . Aber dennoch werde ich nehme an, das Problem groß genug ist, dass die Leistung ist ein Problem.

Wenn die Wörterbuchdatei vorsortiert (wie die meisten sind), und wenn der Text in das Wörterbuch klein ist, wie Sie beschreiben, dann würde ich sehr versucht sein, den Text zu sortieren, vielleicht Duplikate zu entfernen, und dann durchlaufen beide Listen Side-by -side mit dem gleichen Verfahren wie ein Mergesort, außer Sie berichten, ob jeder Text Wort im Wörterbuch ist stattdessen eine vereinigte Liste der Ausgabe.

Dies macht den Job in etwa M log M Vergleiche für die Art, zuzüglich höchstens N + M Vergleiche für die Iteration (möglicherweise weniger, aber nicht die Komplexität weniger). Das ist ziemlich nah an einem optimale Komplexität für einen Betrieb Einmal: die Beseitigung der linearen Term erhalten in N Sie müssen Wege finden, um nicht das ganze Wörterbuch von der Festplatte überhaupt zu lesen. Ich bin mir ziemlich sicher, dass es möglich ist, in die Datei bsearch, zumal Worte recht kurz sind, aber für kleinen N ist es reine Vermutung, ob sucht über den Ort wird tatsächlich schneller als seriell die Daten zugreifen kann.

Es hat die folgenden Eigenschaften:

  • Sie müssen nicht das Wörterbuch im Speicher halten, nur den Text.
  • Trotzdem Sie nur einen Durchlauf über die Wörterbuch-Datei machen.
  • Sie benötigen keine aufwendige Verarbeitung des Wörterbuchs tun.

Natürlich, wenn die Wörterbuch-Datei wird dann nicht sortiert vorbestellt dies nicht funktioniert, und wenn Sie die Wörterbuch rumhängen für die nächste Operation in der Rechtschreibprüfung Speicher halten können, dann können Sie die Kosten für die E / A-amortisieren und von der Verarbeitung zu ein Baum über mehrere verschiedene Texte, die ein Gewinn auf lange Sicht sein.

Wenn das Wörterbuch wirklich sehr groß ist, dann könnten Sie profitieren sie auf der Festplatte in einer vorverarbeiteten Form äquivalent zu einem unausgeglichenen Baum speichert entsprechend die relativen Häufigkeiten der verschiedenen Worte in Ihrer Sprache gewichtet. Dann können Sie tun, weniger als O (N) Plattenzugriff für kleine Texte, und auf den meisten Betriebssystemen stören nicht in den Speicher geladen überhaupt, mmap einfach die Datei und lassen Sie die OS Sorgen darüber. Für ein großes Wörterbuch, das gesamte Cluster Wörter beginnend mit „Dimethyl“ enthält, muss niemals berührt werden.

Eine weitere Überlegung ist ein Splay-Baum für das Wörterbuch. Ein Spreizfuß Baum Unwuchten sich wie Sie die Dinge darin nachschlagen, um zu finden, häufig verwendete Werte schneller zu machen. Die meisten Texte verwenden eine kleine Anzahl von Worten wiederholt, so dass, wenn der Text lang genug ist, den Aufwand zu rechtfertigen dies schließlich gewinnen wird.

Beide oben unterliegen Steven A Lowe Punkt, der für Streicher, ein Trie einen normalen Baum schlägt. obwohl Sie wissen nicht, ob Sie ein Off-the-shelf spreizen trie, finden.

Beantwortet am 05/12/2008 um 03:55
quelle vom benutzer

stimmen
1

Wenn Sie nur, wenn ein bestimmtes Wort in Ihrem Wörterbuch vorhanden ist, um zu sehen versuchen, (das heißt, es richtig geschrieben ist), dann glaube ich nicht, ein binärer Suchbaum ist, was Sie nach. Eine bessere Möglichkeit, diese Informationen speichern würde in einem Baum-Stil, wo jeder aufeinanderfolgenden Knoten auf Ihrem Baum ein Zeichen ist, und zum Endknoten des Pfad zu lesen gibt Ihnen die Schreibweise des Wortes. Sie würden auch einen Marker hinzufügen müssen, um ein Wort-Ende anzuzeigen.

Zum Beispiel: Angenommen, Ihr Wörterbuch diese Worte hat: Auto, Wagen, Katze, Tasse, Schnitt

- C
  - A
    - R
      - end
      - T
    - T
      - end
  - U
    - P
      - end
    - T
      - end

Prüfen, ob ein Wort existiert, ist eine Frage der individuell auf jedem Buchstaben suchen, und dass es existiert in den Kindern des aktuellen Knotens.

Check for "cat"
Does "C" exist at the root level? Yes, move to the next letter.
Does "A" exist underneath C? Yes, move on.
Does "T" exist underneath A? Yes, move on.
Is there a word ending after the T? Yes. Word exists.

Check for "cu"
Does "C" exist at the root level? Yes, move to the next letter.
Does "U" exist at the root level? Yes, move to the next letter.
Is there a word ending after the U? No. Word does not exist.

Wie Sie diese Informationen speichern , ist bis zu Ihnen. Wie Steven wies darauf hin, ein Ternary Search Trie könnte der Weg zu gehen: jeder Knoten 27 möglich Kindknoten haben würde.

Beantwortet am 05/12/2008 um 04:16
quelle vom benutzer

stimmen
3

Sind Sie tot-Set eines binären Suchbaumes auf der Verwendung? Ein Bloom - Filter wäre wahrscheinlich eine effizientere Datenstruktur sein.

Beantwortet am 05/12/2008 um 04:34
quelle vom benutzer

stimmen
0

Sehen, dass dies eine Hausaufgabe Frage ist, ich gehe davon aus, dass Sie einen einfachen alten binären Baum verwenden (keine Rot-Schwarz Bäume, AVL-Bäume, Radix Bäume, etc.). Die Antwort ist dann zu versuchen, der Baum im Gleichgewicht zu halten, wie Sie es aus der Wortliste erstellen. Ein Ansatz ist die Liste vor dem Lesen sie in randomisieren, gibt diese vernünftige Ergebnisse. Aber Sie können bessere Ergebnisse, wenn Sie die Eingabesequenz bestellen (mit der gleichen Vergleich wie das, was der Baum verwendet), dann unterteilen rekursiv die Eingabe der Rückkehr den Mittelpunkt, bis keine Elemente bleiben. Das Ergebnis ist ein ausgeglichener Baum.

Ich klopfte auf drei verschiedene Arten davon in C # zu tun:

private static IEnumerable<T> BinaryTreeOrder<T>(IList<T> range, int first, int last)
{
  if (first > last)
  {
    yield break;
  }

  int mid = (first + last) / 2;
  yield return range[mid];
  foreach (var item in BinaryTreeOrder(range, first, mid - 1))
  {
    yield return item;
  }
  foreach (var item in BinaryTreeOrder(range, mid + 1, last))
  {
    yield return item;
  }    
}

private static void BinaryTreeOrder<T>(IList<T> range, int first, int last, 
                                       ref IList<T> outList)
{
  if (first > last)
  {
    return;
  }

  int mid = (first + last) / 2;
  outList.Add(range[mid]);
  BinaryTreeOrder(range, first, mid - 1, ref outList);
  BinaryTreeOrder(range, mid + 1, last, ref outList);
}

private static void BinaryTreeOrder<T>(IList<T> range, int first, int last, 
                                       ref BinaryTree<T> tree) where T : IComparable<T>
{
  if (first > last)
  {
    return;
  }

  int mid = (first + last) / 2;
  tree.Add(range[mid]);
  BinaryTreeOrder(range, first, mid - 1, ref tree);
  BinaryTreeOrder(range, mid + 1, last, ref tree);
}
Beantwortet am 20/04/2011 um 21:27
quelle vom benutzer

stimmen
1

Diese Seite soll Ihnen helfen, es die Implementierung in Java hat.

Beantwortet am 12/06/2011 um 04:07
quelle vom benutzer

stimmen
0

Wie bereits angedeutet wäre ein Trie effizienter als ein binärer Baum, aber Sie können einen hashmap verwenden und jedes Wort Hash. Sie haben ein kleines Wörterbuch (1000 Einträge). Wie Sie Ihr Dokument durchlaufen, überprüfen, ob die Worte im hashmap sind. Wenn sie es nicht sind, wird das Wort falsch geschrieben angenommen werden.

Dies wird Ihnen nicht möglich, eine Korrektur auf ein falsch geschriebenes Wort. Es sagt Ihnen, nur ja oder nein (richtig oder nicht).

Wenn Sie Rechtschreibvorschläge für falsche Worte wollen, können Sie aus dem Wort in der Datei starten, erzeugen dann alle Worte 1 Bearbeitung entfernt und diese als Kinder des ursprünglichen Wortes hinzufügen. Auf diese Weise bauen Sie ein Diagramm. Go 2 Ebenen tief für maximale Geschwindigkeit vs Genauigkeit. Wenn Sie ein Wort Knoten erzeugen, die im Wörterbuch enthalten ist, können Sie es auf eine Liste der möglichen Vorschläge hinzufügen. Am Ende kehren die Liste der möglichen Vorschläge.

Für eine bessere Rechtschreibprüfung, versuchen auch in Lautanpassung hinzuzufügen.

Meer Yuh -> siehe yah

Diese Methode (von Graphen von Strings 1 bearbeiten weg zu schaffen) ist „langsam“. Aber es ist eine gute akademische Übung. Laufzeit ist O (n ^ Verzweigungen).

Wenn hier interessiert ist , einen Link zu einem Ich baute mich (zum Spaß): https://github.com/eamocanu/spellcheck.graph

Einige Beispielgraphen: https://github.com/eamocanu/spellcheck.graph/tree/master/graph%20photos

Ich habe auch eine UI-Komponente, um es, die diese Graphen erzeugt. Dies ist eine externe Bibliothek.

Beantwortet am 15/12/2011 um 22:26
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more