L'utilisation d'un arbre de recherche binaire comme un correcteur orthographique

voix
4

Vous vous demandez la façon la plus efficent faire un arbre de recherche binaire dans un correcteur orthographique en lisant mot 1000 mots fichier dictionnaire, puis l'avoir vérifier un autre document que dire a un paragraphes couple.

Créé 05/12/2008 à 03:05
source utilisateur
Dans d'autres langues...                            


8 réponses

voix
8

un arbre ternaire Trie serait plus efficace

Créé 05/12/2008 à 03:22
source utilisateur

voix
0

Si vous devez faire une recherche automatique suggère / préfixe ainsi, puis un arbre d'arbre de patricia ou radix est intéressant de regarder.

Créé 05/12/2008 à 03:26
source utilisateur

voix
0

Avec l'exemple que vous avez donné, la performance est susceptible d'être hors de propos, puisque sur un PC l'opération prendra environ 1% du temps nécessaire à l'utilisateur de lire le premier résultat vous montrer, à condition de ne pas utiliser un algorithme complètement stupide . Mais encore, je suppose que le problème est assez grand pour que la performance est un problème.

Si le fichier du dictionnaire est prétrié (comme la plupart sont), et si le texte est faible par rapport au dictionnaire que vous décrivez, alors je serais bien tenté de trier le texte, la suppression peut-être des doublons, puis itérer les deux listes côte -side en utilisant la même procédure comme une sorte de fusion, sauf vous indiquer si chaque mot texte est dans le dictionnaire au lieu de produire une liste fusionnée.

Cela fait le travail dans environ M comparaisons M journal pour le genre, ainsi que dans la plupart des comparaisons N + M pour l'itération, (peut-être moins, mais non moins complexe). C'est assez proche de la complexité optimale pour une opération unique: pour se débarrasser du terme linéaire en N, vous devez trouver des moyens de ne pas lire le dictionnaire entier de disque du tout. Je suis sûr qu'il est possible de BSEARCH dans le fichier, en particulier étant donné que les mots sont assez courts, mais pour les petits N c'est je vous laisse deviner si la recherche de l'endroit sera effectivement plus rapide que série d'accéder aux données.

Il présente les caractéristiques suivantes:

  • Vous ne devez pas tenir le dictionnaire en mémoire, seul le texte.
  • Néanmoins, vous faites une seule passe sur le fichier dictionnaire.
  • Vous ne faites pas le traitement coûteux du dictionnaire.

Bien sûr, si le fichier du dictionnaire est pré-trié alors cela ne fonctionne pas non, et si vous pouvez garder le dictionnaire traîner en mémoire pour la prochaine opération de vérification orthographique, vous pouvez amortir le coût d'E / S et de sa transformation en un arbre à travers plusieurs textes différents, qui sera une victoire à long terme.

Si le dictionnaire est vraiment énorme, alors vous pourriez bénéficier de stocker sur le disque sous une forme pré-traitées équivalent à un arbre non équilibré pondéré en fonction des fréquences relatives des différents mots dans votre langue. Ensuite, vous pouvez le faire à moins de O (N) l'accès au disque pour les petits textes, et sur la plupart des systèmes d'exploitation pas pris la peine de le charger dans la mémoire du tout, juste MMap le fichier et laisser le souci du système d'exploitation à ce sujet. Pour un grand dictionnaire, les clusters entiers contenant les mots commençant par « diméthyle » besoin jamais touché.

Une autre considération est un arbre évasement pour le dictionnaire. Un arbre évasement se que vous regardez déséquilibre les choses en elle, afin de rendre les valeurs fréquemment utilisées plus rapide à trouver. La plupart des textes utilise un petit nombre de mots à plusieurs reprises, donc si le texte est assez long pour justifier les frais généraux de cette gagnera par la suite.

Les deux ci-dessus sont soumis à Steven A point de Lowe que pour les chaînes, un arbre bat Trie normal. Je ne sais pas si vous trouverez un impromptu évasement Trie, cependant.

Créé 05/12/2008 à 03:55
source utilisateur

voix
1

Si vous êtes juste essayer de voir si un mot existe dans votre dictionnaire (qui est, il est correctement orthographié), alors je ne pense pas un arbre de recherche binaire est ce que vous êtes après. Une meilleure façon de stocker cette information serait dans un style arbre où chaque noeud successif sur votre arbre est un caractère, et la lecture du chemin vers le noeud final vous donne l'orthographe de ce mot. Vous auriez besoin également d'ajouter un marqueur pour indiquer un mot fin.

Par exemple: dire votre dictionnaire a ces mots: voiture, charrette, chat, coupe, coupe

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

Vérifier si un mot existe est une question de regarder chaque lettre individuellement, et qu'il existe chez les enfants du noeud courant.

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.

Comment vous stockez cette information est à vous. Comme l' a souligné Steven sur une recherche ternaires Trie pourrait être le chemin à parcourir: chaque nœud aurait 27 nœuds enfants possibles.

Créé 05/12/2008 à 04:16
source utilisateur

voix
3

Êtes - vous mort fixé sur l' aide d' un arbre de recherche binaire? Un filtre de Bloom serait probablement une structure de données plus efficace.

Créé 05/12/2008 à 04:34
source utilisateur

voix
0

Voyant que cela est une question de devoirs, je vais supposer que vous devez utiliser un vieil arbre binaire simple (pas d'arbres rouge-noir, AVL, arbres Radix, etc.). La réponse est alors d'essayer de garder l'arbre équilibré que vous construisez à partir de la liste de mots. Une approche consiste à randomiser la liste avant de le lire, on obtient alors des résultats raisonnables. Mais vous pouvez obtenir de meilleurs résultats si vous commandez la séquence d'entrée (en utilisant la même comparaison que ce que l'arbre utilise), puis lotir récursive l'entrée de retour du milieu jusqu'à ce qu'il ne reste des éléments. Le résultat est un arbre équilibré.

Je frappai en trois différentes façons de le faire en C #:

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);
}
Créé 20/04/2011 à 21:27
source utilisateur

voix
1

Ce site devrait vous aider a la mise en œuvre en java.

Créé 12/06/2011 à 04:07
source utilisateur

voix
0

Comme l'a suggéré une structure arborescente serait plus efficace qu'un arbre binaire, mais vous pouvez utiliser une table de hachage et de hachage chaque mot. Vous avez un petit dictionnaire (1000 entrées). Comme vous traversez votre document, vérifier si les mots sont dans le hashmap. S'ils ne sont pas, le mot est supposé être mal orthographié.

Cela vous ne donnera pas la correction possible à un mot mal orthographié. Il vous dit oui ou non (correct ou non).

Si vous voulez des suggestions d'orthographe pour les mots incorrects, vous pouvez commencer à partir du mot dans le fichier, puis générer tous les mots 1 distance modifier loin et les ajouter en tant qu'enfants du mot initial. De cette façon, vous construisez un graphique. Aller 2 niveaux de profondeur pour une vitesse maximale par rapport précision. Si vous créez un nœud de mot qui est dans le dictionnaire, vous pouvez l'ajouter à une liste de suggestions. A la fin, le retour de la liste des suggestions.

Pour une meilleure vérification orthographique, essayez également d'ajouter en correspondance phonétique.

mer Yuh -> voir yah

Cette méthode (de créer des graphiques de chaînes 1 modifier l'écart) est « lent ». Mais il est un bon exercice académique. Runtime est O (n ^ branches).

Si vous êtes intéressé ici est un lien vers celui que je me suis construit (pour le plaisir): https://github.com/eamocanu/spellcheck.graph

Quelques exemples graphiques: https://github.com/eamocanu/spellcheck.graph/tree/master/graph%20photos

J'ai également ajouté un composant d'interface utilisateur pour ce qui génère les graphiques. Ceci est une bibliothèque externe.

Créé 15/12/2011 à 22:26
source utilisateur

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