Je suis intéressé par les essais et les DAWG (graphe de mots acycliques directs) et j'ai beaucoup lu à leur sujet, mais je ne comprends pas à quoi devrait ressembler le trie de sortie ou le fichier DAWG.
- Un trie doit-il faire l'objet de dictionnaires imbriqués? Où chaque lettre est divisée en lettres et ainsi de suite?
- Une recherche effectuée sur un tel dictionnaire serait-elle rapide s'il y a 100 000 ou 500 000 entrées?
- Comment implémenter des blocs de mots composés de plus d'un mot séparés par
-
un espace ou? - Comment lier le préfixe ou le suffixe d'un mot à une autre partie de la structure? (pour DAWG)
Je veux comprendre la meilleure structure de sortie afin de comprendre comment en créer et en utiliser une.
J'apprécierais également ce que devrait être la sortie d'un DAWG avec trie .
Je ne veux pas voir de représentations graphiques avec des bulles liées les unes aux autres, je veux connaître l'objet de sortie une fois qu'un ensemble de mots est transformé en essais ou DAWG.
Réponses:
Unwind est essentiellement correct qu'il existe de nombreuses façons différentes de mettre en œuvre un trie; et pour un trie volumineux et évolutif, les dictionnaires imbriqués peuvent devenir encombrants - ou du moins peu efficaces en termes d'espace. Mais puisque vous ne faites que commencer, je pense que c'est l'approche la plus simple; vous pouvez coder un simple
trie
en quelques lignes. Tout d'abord, une fonction pour construire le trie:Si vous n'êtes pas familier avec
setdefault
, il recherche simplement une clé dans le dictionnaire (ici,letter
ou_end
). Si la clé est présente, elle renvoie la valeur associée; sinon, il attribue une valeur par défaut à cette clé et renvoie la valeur ({}
ou_end
). (C'est comme une version deget
qui met également à jour le dictionnaire.)Ensuite, une fonction pour tester si le mot est dans le trie:
Je vous laisse l'insertion et le retrait comme un exercice.
Bien sûr, la suggestion de Unwind ne serait pas beaucoup plus difficile. Il pourrait y avoir un léger inconvénient de vitesse en ce que la recherche du sous-nœud correct nécessiterait une recherche linéaire. Mais la recherche serait limitée au nombre de caractères possibles - 27 si nous incluons
_end
. De plus, il n'y a rien à gagner en créant une liste massive de nœuds et en y accédant par index comme il le suggère; vous pouvez tout aussi bien imbriquer les listes.Enfin, j'ajouterai que créer un graphe de mot acyclique dirigé (DAWG) serait un peu plus complexe, car vous devez détecter les situations dans lesquelles votre mot actuel partage un suffixe avec un autre mot dans la structure. En fait, cela peut devenir assez complexe, selon la façon dont vous souhaitez structurer le DAWG! Vous devrez peut-être apprendre des choses sur la distance de Levenshtein pour bien faire les choses.
la source
dict.setdefault()
(il est sous-utilisé et pas assez connu), en partie parce qu'il aide à éviter les bogues trop faciles à créer avec undefaultdict
(où vous n'obtiendrez pas deKeyError
clés non existantes lors de l'indexation). La seule chose maintenant qui le rendrait utilisable pour le code de production est d'utiliser_end = object()
:-)Jetez un œil à ceci:
https://github.com/kmike/marisa-trie
Voici un article de blog d'une entreprise utilisant marisa trie avec succès:
https://www.repustate.com/blog/sharing-large-data-structure-across-processes-python/
Il existe également quelques implémentations purement python, mais à moins que vous ne soyez sur une plate-forme restreinte, vous souhaiterez utiliser l'implémentation C ++ ci-dessus pour de meilleures performances:
la source
Voici une liste de packages python qui implémentent Trie:
la source
Modifié à partir de
senderle
la méthode de (ci-dessus). J'ai trouvé que Pythondefaultdict
est idéal pour créer un trie ou un arbre de préfixes.la source
Il n'y a pas de "devrait"; c'est à vous. Diverses implémentations auront des caractéristiques de performances différentes, prendront un certain temps à implémenter, à comprendre et à bien faire. C'est typique du développement logiciel dans son ensemble, à mon avis.
J'essaierais probablement d'abord d'avoir une liste globale de tous les nœuds de trie créés jusqu'à présent, et de représenter les pointeurs enfants dans chaque nœud comme une liste d'indices dans la liste globale. Avoir un dictionnaire juste pour représenter l'enfant qui relie me semble trop lourd.
la source
Si vous voulez un TRIE implémenté en tant que classe Python, voici quelque chose que j'ai écrit après avoir lu à leur sujet:
la source
Cette version utilise la récursivité
Production:
la source
Définissez Trie:
Créer Trie:
Chercher:
Tester:
la source
True
ne renvoie que pour un mot entier, mais pas pour le préfixe, pour le changement de préfixereturn '_end' in curr
enreturn True
En dehors
la source
Classe Python pour Trie
La structure de données Trie peut être utilisée pour stocker des données dans
O(L)
lesquelles L est la longueur de la chaîne, de sorte que pour l'insertion de N chaînes, la complexité du temps serait queO(NL)
la chaîne puisse être recherchée dansO(L)
que pour la suppression.Peut être cloné à partir de https://github.com/Parikshit22/pytrie.git
Code Oputpt
Vrai
Faux
[ 'Minakshi', 'Minhaj']
7
Minakshi
minhajsir
pari
Parikshit
shubh
shubham
shubhi
la source