J'écris une application qui a besoin de lire une liste de chaînes à partir d'un fichier, les enregistrer dans une structure de données, puis Recherchez ces chaînes par des préfixes. La liste des chaînes est simplement une liste de mots dans une langue donnée. Par exemple, si la fonction de recherche obtient "stup" comme paramètre, elle devrait retourner ["stupide", "stupidité", "stupeur" ...]. Il devrait le faire en O (log (n) * m), où n est la taille de la structure de données et m est le nombre de résultats et devrait être aussi rapide que possible. La consommation de mémoire n'est pas un gros problème en ce moment. J'écris ceci en python, donc ce serait génial si vous pouviez me diriger vers une structure de données appropriée (de préférence) implémentée en c avec des wrappers python.structure de données la plus efficace pour une liste de chaînes en lecture seule (environ 100 000) avec recherche de préfixe rapide
Répondre
Vous voulez un trie.
http://en.wikipedia.org/wiki/Trie
Je les ai utilisés dans les programmes de Scrabble et Boggle. Ils sont parfaits pour le cas d'utilisation que vous avez décrit (recherche de préfixe rapide).
Voici un exemple de code pour construire un trie en Python. Cela vient d'un programme Boggle que j'ai monté ensemble il y a quelques mois. Le reste est laissé comme un exercice au lecteur. Mais pour la vérification des préfixes, vous avez besoin d'une méthode qui commence au nœud racine (la variable words
), qui suit les lettres du préfixe aux nœuds enfants successifs, et renvoie Vrai si un tel chemin est trouvé et Faux dans le cas contraire.
class Node(object):
def __init__(self, letter='', final=False):
self.letter = letter
self.final = final
self.children = {}
def __contains__(self, letter):
return letter in self.children
def get(self, letter):
return self.children[letter]
def add(self, letters, n=-1, index=0):
if n < 0: n = len(letters)
if index >= n: return
letter = letters[index]
if letter in self.children:
child = self.children[letter]
else:
child = Node(letter, index==n-1)
self.children[letter] = child
child.add(letters, n, index+1)
def load_dictionary(path):
result = Node()
for line in open(path, 'r'):
word = line.strip().lower()
result.add(word)
return result
words = load_dictionary('dictionary.txt')
Un trie (or prefix tree) sonne bien dans votre rue. Il peut faire la recherche sur une chaîne de préfixe de longueur m dans O (m) je crois.
matrice de chaînes.
puis recherche binaire pour rechercher par le premier match étape puis un par un à travers elle pour tous les matches ultérieurs
(i avais initialement liste chaînée ici aussi ... mais bien sûr, cela ne doit pas au hasard l'accès était donc ce « bs » (ce qui explique sans doute pourquoi je downvoted) Mon algorithme de recherche binaire est toujours le moyen le plus rapide d'aller si
mon dieu, donne une pause au gars. – moo
tant de downvotes, et personne ne se soucie d'expliquer pourquoi? C'est comme si les gens s'entassaient juste dessus. Cette réponse répond à toutes les contraintes demandées par l'utilisateur initial et est plus simple à comprendre et à maintenir. –
@reinier - J'imagine que vous êtes downvoted car les listes liées ne sont pas bonnes pour l'accès aléatoire, donc votre temps de recherche est linéaire dans le nombre d'éléments. Un tableau serait rapide (ish) s'il était déjà trié, mais ce serait O (log n), alors qu'un trie est O (m), où m est la longueur du préfixe. –
- 1. Le moyen le plus rapide d'obtenir des vidéos YouTube pour plus de 100 000 chansons
- 2. Insertion efficace et recherche de chaînes
- 3. Une comparaison de chaînes ou une recherche de hachage est-elle plus rapide en Perl?
- 4. Transfert de 100 000 images vers S3. Quel est le moyen le plus rapide?
- 5. Meilleure structure de données pour la recherche?
- 6. Structure de données espace-efficace pour stocker une liste de mots?
- 7. Quelle est la structure de données la plus efficace pour contenir des mots-clés?
- 8. Rendre l'élément DOM efficace en lecture seule
- 9. Quelle est la meilleure structure de données pour mapper les chaînes aux valeurs?
- 10. stratégie de suppression de ligne la plus efficace pour QStandardItemModel
- 11. Structure de données la plus efficace pour représenter les commentaires threadés en Java?
- 12. La méthode de copie la plus rapide/la plus efficace entre S3 et EC2?
- 13. La structure de données la plus appropriée pour une liste ordonnée dans un SGBDR?
- 14. Structure de données pour la conception d'un cache avec insertion efficace, suppression et récupération de la valeur la plus élevée
- 15. Structure de données efficace pour comparer les éléments avec les attributs les plus courants
- 16. Quelle est la meilleure façon de créer un index pour obtenir la réponse de lecture la plus rapide?
- 17. Comment supprimer des fichiers via FTP lorsque le répertoire contient plus de 100 000 fichiers?
- 18. Connexion à une base de données en lecture seule
- 19. Linq to NHibernate générant plus de 3 000 requêtes SQL en une seule requête!
- 20. moyen le plus rapide de comparer une chaîne avec un tableau de chaînes en C# 2.0
- 21. Structure de recherche pour les messages d'erreur
- 22. Quelle est la meilleure structure de données pour les données arborescentes de profondeur fixe en C#?
- 23. Quelle est la manière la plus rapide (exécution de code) d'exécuter une lecture XML?
- 24. PHP plus efficace si structure
- 25. Formulaire de recherche url structure
- 26. Le moyen le plus rapide de copier une seule grande table (30 000 lignes) d'une base de données à une autre?
- 27. Recherche rapide dans une grande liste avec jQuery
- 28. Une alternative plus rapide à la fonction .html de jQuery?
- 29. lecture seule liste avec des propriétés automatiques
- 30. Afficher avec une colonne en lecture seule
je serais tenté d'écrire Node.add() comme méthode itérative: ajouter def (auto, lettres): suivant = self n = len (lettres) pour l'index, lettre en énumérer (lettres): sinon (lettre dans next.children): next.children [lettre] = Node (lettre, index == n-1) next = next.children [ lettre] – hughdbrown
Mais essayez d'imaginer cela avec une indentation et une ligne correctes pauses. – hughdbrown
Voir également "DAWG", qui est un trie qui utilise moins de mémoire. Mais c'est compliqué à construire (au moins par rapport à un trie). – Fantius