Trouver les anagrammes d'un mot donné
Deux mots sont des anagrammes si l'un d'eux a exactement les mêmes caractères que celle d'un autre mot.
Exemple : Anagram
& Nagaram
sont des anagrammes (insensible à la casse).
Maintenant il ya beaucoup de questions similaires à ce . Un couple d'approches pour trouver si les deux chaînes sont des anagrammes sont :
1) Sort
les cordes et de les comparer.
2) Créer un frequency map
de ces chaînes et de vérifier si elles sont identiques ou non.
Mais dans ce cas , nous sont données avec un mot (par souci de simplicité, nous supposons un seul mot seulement, et il sera seul mot anagrammes seulement) et nous avons besoin de trouver les anagrammes pour que.
Solution que j'ai à l'esprit est que , nous pouvons générer toutes les permutations de la parole et de vérifier lequel de ces mots existe pas dans le dictionnaire . Mais clairement , c'est très inefficace. Oui , le dictionnaire est aussi disponible.
Donc quelles alternatives avons-nous ici ?
J'ai aussi lu dans un même thread que quelque chose peut être fait en utilisant Tries
mais la personne n'a pas expliqué à ce que l'algorithme était et pourquoi nous utilisons un Trie dans la première place , juste une mise en œuvre a été fourni que de trop en Python ou Ruby. Donc ce n'était pas vraiment utile, c'est pourquoi j'ai créé ce fil. Si quelqu'un veut partager leur mise en œuvre (autre que C,C++ ou Java), puis de bien vouloir l'expliquer aussi.
- Quelque chose pour vous aider à la recherche d'une réponse: stackoverflow.com/questions/7896694/... Fondamentalement, ce que vous pouvez faire est d'avoir de fonction de hachage qui rapporte la même valeur pour les anagrammes, et ensuite de les convertir votre dictionnaire à une structure qui permet de récupérer la liste des mots tels hachage.
- Que voulez-vous vraiment faire ? Trouver tous les anagrammes qui existe dans un dictionnaire à partir d'un ensemble donné de lettres ? Ou de construire une anagramme rapport sur tous les mots dans un dictionnaire, c'est à dire étant donné un mot dans le dictionnaire, récupérer de manière efficace tous les valides anagrammes ?
- Étant donné un dictionnaire avec un ensemble fixe de mots , et un mot au hasard (ou peut-être pas dans le dictionnaire) , trouver ses anagrammes (qui sont présents dans le dictionnaire). Du sens?
Vous devez vous connecter pour publier un commentaire.
Exemple d'algorithme:
Pour vérifier tous les anagrammes d'un mot donné:
Relativement rapide à construire, hyper rapide sur look-up.
O(n)
,O(log(n))
etc) aurait été mieux.O(w n log(w))
à construire et àO(w log(w))
sur la recherche, en moyenne, oùw
est la moyenne de la longueur des mots dans le dictionnaire etn
est le dictionnaire de la longueur.Je suis venu avec une nouvelle solution je pense. Il utilise le Théorème Fondamental de l'Arithmétique. L'idée est donc d'utiliser un tableau de 26 premiers nombres premiers. Ensuite, pour chaque lettre dans le mot d'entrée nous obtenons le correspondant de nombre premier A = 2, B = 3, C = 5, D = 7 ... et puis nous calculons le produit de notre mot d'entrée. Ensuite, nous faisons cela pour chaque mot dans le dictionnaire, et si un mot correspond à notre mot d'entrée, puis on l'ajoute à la liste des résultats. Tous les anagrammes possèdent la même signature, car
Voici le code. - Je convertir le mot en MAJUSCULES et 65 ans est la position de l'Un qui correspond à mon premier nombre premier:
C'est la méthode:
Sorting is a bit more expensive than multiplication
bon point. Dans ce cas, je crois que je préfère votre approche à l'aide de nombres premiers. Je vais chercher plus loin.ord(chr)
ou similaire va être au moins aussi longue que triées caractères dans les mots. Personne n'a le temps de ce dans n'importe quelle langue?Nous savons que si les deux mots n'ont pas la même longueur, ils ne sont pas des anagrammes. De sorte que vous pouvez partitionner votre dictionnaire dans les groupes de mots de même longueur.
Maintenant nous concentrer sur un seul de ces groupes et, fondamentalement, tous les mots ont exactement la même longueur dans ce petit univers.
Si chaque lettre de position est une dimension, et la valeur de cette dimension est basée sur la lettre (dire le code ASCII). Ensuite, vous pouvez calculer la longueur du vecteur de mot.
Par exemple, dire 'A'=65, B=66, puis
length("AB") = sqrt(65*65 + 66*66)
. Évidemment,length("AB") = length("BA")
.Clairement, si deux mots sont des anagrammes, puis leurs vecteurs ont la même longueur. La prochaine question est de savoir si deux mots (de même nombre de lettres) de vecteurs ont la même longueur, sont-ils des anagrammes? Intuitivement, je dirais que non, puisque tous les vecteurs de cette longueur, forme une sphère, il y a beaucoup de. Pas sûr, puisque nous sommes dans l'entier de l'espace dans ce cas, combien il y en a en réalité.
Mais à tout le moins, il permet de partitionner votre dictionnaire encore plus loin. Pour chaque mot dans votre dictionnaire, calculer le vecteur de distance:
for(each letter c) { distance += c*c }; distance = sqrt(distance);
Puis créer une carte pour tous les mots de longueur
n
, et avec la distance et la valeur est une liste de mots de longueurn
que le rendement de cette distance.Vous allez créer une carte pour chaque distance.
Alors votre recherche devient l'algorithme suivant:
Bien Essaie de le rendre plus facile à vérifier si le mot existe.
Donc, si vous placez l'ensemble de dictionnaire dans un trie:
http://en.wikipedia.org/wiki/Trie
ensuite vous pourrez par la suite prendre la parole et faire simple retour en arrière en prenant un char et de façon récursive de vérifier si l'on peut "marcher" en bas de la Trie avec tout combiniation du reste de la station (ajout d'un char à un moment). Lorsque tous les caractères sont utilisés dans une récursivité de la branche et il y avait un chemin d'accès valide dans la Trie, puis le mot existe.
La Trie aide parce que son une belle condition d'arrêt:
Nous pouvons vérifier si la partie de la chaîne, de l'e.g "Anag" est un chemin d'accès valide dans la trie, si l'on peut briser particulier la récursivité de la branche. Cela signifie que nous n'avons pas de vérifier chaque permutation des caractères.
En pseudo-code
Évidemment vous avez besoin d'une belle Trie discbased qui vous permet de progressivement à "marcher" en bas de l'arbre et de vérifier à chaque nœud si il y a un chemin avec le char à tout nœud suivant...
clojure.string/lower-case
).group-by
) par lettre de la fréquence de la carte (frequencies
).(
These
) sont les fonctions correspondantes dans le dialecte de Lisp Clojure.L'ensemble de la fonction peut être exprimée ainsi:
Par exemple,
Une fonction d'indexation qui fait correspondre chaque chose à sa collection est
De sorte que, par exemple,
... où
comp
est la fonctionnelle de la composition de l'opérateur.Générer toutes les permutations est facile, je suppose que vous êtes inquiet à ce que la vérification de leur existence dans le dictionnaire est "hautement inefficace" partie. Mais cela dépend en réalité de ce que la structure de données que vous utilisez pour le dictionnaire: bien sûr, une liste de mots serait inefficace pour votre cas d'utilisation. En parlant de Essaie, ce serait probablement une représentation idéale, et assez efficace, aussi.
Une autre possibilité serait de faire quelques pré-traitement dans votre dictionnaire, par exemple, construire une table de hachage dont les clés sont les mots en lettres triées, et les valeurs sont des listes de mots. Vous pouvez même sérialiser cette table de hachage de sorte que vous pouvez l'écrire dans un fichier et de le recharger rapidement plus tard. Alors pour chercher des anagrammes, il vous suffit de trier votre mot donné et recherchez l'entrée correspondante dans la table de hachage.
Qui dépend de la façon dont vous stockez votre dictionnaire. Si c'est un simple tableau de mots, pas d'algorithme sera plus rapide que linéaire.
Si elle est triée, puis ici, c'est une approche qui peut fonctionner. Je l'ai inventé tout à l'heure, mais je suppose que c'est plus rapide que l'approche linéaire.
C'est comment j'allais le faire, de toute façon. Il devrait y avoir une approche plus conventionnelle, mais c'est plus rapide, puis linéaire.
essayé de mettre en œuvre la table de hachage solution
projet de chaque mot du dictionnaire du comte de vecteur dans cette direction au hasard et de stocker la valeur de (insérez tels que le tableau de valeurs est triée).
Donné un nouveau test de la parole, du projet dans la même direction au hasard utilisé pour les mots du dictionnaire.
PS: La procédure ci-dessus est une généralisation du premier numéro de procédure qui peuvent potentiellement conduire à un grand nombre (et donc de calcul de la précision des questions)
Une solution est -
Carte des nombres premiers de lettres de l'alphabet et de multiplier le premier numéro de
Donc
Obtenir MUL_number pour la parole Donnée. retour à tous les mots de dictionnaire, qui ont même MUL_number comme mot donné
D'abord vérifier si la longueur des chaînes de caractères sont les mêmes.
ensuite, vérifiez si la somme des caractères les chaînes de caractères sont les mêmes (c'est à dire le code ascii somme)
puis les mots sont des anagrammes
d'autre pas un anagramme