web-dev-qa-db-fra.com

Quel est le meilleur algorithme de saisie semi-automatique / suggestion, structure de données [C ++ / C]

Nous voyons Google, Firefox quelques pages AJAX affichent une liste d'éléments probables pendant que l'utilisateur tape des caractères.

Quelqu'un peut-il donner un bon algorithme, une structure de données pour implémenter la saisie semi-automatique?

48
subbul

Un trie est une structure de données qui peut être utilisée pour trouver rapidement des mots qui correspondent à un préfixe.

Modifier: voici un exemple montrant comment en utiliser un pour implémenter la saisie semi-automatique http://rmandvikar.blogspot.com/2008/10/trie-examples.html

Voici une comparaison de 3 différents implémentations auto-complétées (bien que ce soit en Java pas C++).

* In-Memory Trie
* In-Memory Relational Database
* Java Set

Lorsque vous recherchez des clés, le trie est légèrement plus rapide que l'implémentation Set. Le trie et l'ensemble sont un peu plus rapides que la solution de base de données relationnelle.

Le coût d'installation de l'ensemble est inférieur à la solution Trie ou DB. Vous devez décider si vous construisez fréquemment de nouveaux "ensembles de mots" ou si la vitesse de recherche est la priorité la plus élevée.

Ces résultats sont en Java, votre kilométrage peut varier avec une solution C++.

58
Glen

Pour les grands ensembles de données, un bon candidat pour le backend serait les arbres de recherche ternaires. Ils combinent le meilleur de deux mondes: la surcharge d'espace faible des arbres de recherche binaires et l'efficacité temporelle basée sur les caractères des essais de recherche numérique.

Voir dans Dr. Dobbs Journal: http://www.ddj.com/windows/184410528

Le but est la récupération rapide d'un jeu de résultats fini au fur et à mesure que l'utilisateur tape. Considérons d'abord que pour rechercher "informatique", vous pouvez commencer à taper à partir de "ordinateur" ou "science" mais pas "ordinateur". Donc, étant donné une phrase, générez les sous-phrases commençant par un mot. Maintenant, pour chacune des phrases, introduisez-les dans le TST (arbre de recherche ternaire). Chaque nœud du TST représentera un préfixe d'une phrase qui a été tapée jusqu'à présent. Nous stockerons les 10 meilleurs résultats (par exemple) pour ce préfixe dans ce nœud. S'il y a beaucoup plus de candidats que la quantité finie de résultats (10 ici) pour un nœud, il devrait y avoir une fonction de classement pour résoudre la concurrence entre deux résultats.

L'arbre peut être construit toutes les quelques heures, selon le dynamisme des données. Si les données sont en temps réel, je suppose qu'un autre algorithme donnera un meilleur équilibre. Dans ce cas, l'exigence absolue est la récupération ultra-rapide des résultats pour chaque frappe tapée, ce qu'il fait très bien.

D'autres complications surviendront si la suggestion de corrections orthographiques est impliquée. Dans ce cas, les algorithmes de modification de distance devront également être pris en compte.

Pour les petits ensembles de données comme une liste de pays, une simple implémentation de Trie fera l'affaire. Si vous prévoyez d'implémenter une telle liste déroulante de saisie semi-automatique dans une application Web, le widget de saisie semi-automatique de YUI3 fera tout pour vous après avoir fourni les données dans une liste. Si vous utilisez YUI3 uniquement comme interface pour une saisie semi-automatique appuyée par des données volumineuses, créez les services Web basés sur TST en C++, puis utilisez la source de données du nœud de script du widget de saisie semi-automatique pour extraire des données du service Web au lieu d'une simple liste.

19
Joy Dutta

Arbres de segments peut être utilisé pour implémenter efficacement auto complete

6
r15habh

Si vous souhaitez suggérer les compléments les plus populaires, un "arbre de suggestion" peut être un bon choix: arbre de suggestion

4
Nicolai

Pour une solution simple: vous générez un "candidat" avec une distance d'édition minimale ( Levenshtein ) (1 ou 2) puis vous testez l'existence du candidat avec un conteneur de hachage ( set suffira pour une simple solution, puis utilisez unordered_set depuis le tr1 ou boost).

Exemple: vous avez écrit carr et vous voulez voiture. arr est généré par 1 suppression. Arr est dans votre unordered_set? Non. Crr est généré par 1 suppression. Est-ce que crr est dans votre unordered_set? No. car est généré par 1 suppression. La voiture est-elle dans votre ensemble non ordonné? Oui, vous gagnez.

Bien sûr, il y a insertion, suppression, transposition etc ...

Vous voyez que votre algorithme de génération de candidats est vraiment là où vous perdez du temps, surtout si vous avez très peu unordered_set .

2
anno