2010-10-21 2 views
5

Compte tenu de la table de base de données suivante:Existe-t-il un meilleur moyen de trouver des anagrammes en utilisant SQL?

WORDS 
alphagram....varchar(15) 
word.........varchar(15) PK 
length.......int 

Où:

  • 'Alphagram' est les lettres d'un mot dans l'ordre alphabétique (par exemple AEINNRTT est le Alphagram de INTRANET)
  • la clé primaire est 'mot', et il y a des index sur alphagram et la longueur

J'ai trouvé un moyen de trouver les anagrammes d'une chaîne de lettre donnée s via SQL. Par exemple, pour trouver les anagrammes de AEINNRTT cela fonctionnera:

select alphagram, word, definition 
from words 
where length = 8 
and alphagram like '%A%' 
and alphagram like '%E%' 
and alphagram like '%I%' 
and alphagram like '%NN%' 
and alphagram like '%R%' 
and alphagram like '%TT%' 

qui renverra 1 rang (pour INTRANET)

Et si je voulais inclure un nombre connu de caractères génériques, par exemple, combien de les mots sont avec INTRANET + un blanc (joker) Je dois juste changer la 'longueur' au nombre total de lettres + nombre de jokers

select alphagram, word, definition 
from words 
where length = 9 
and alphagram like '%A%' 
and alphagram like '%E%' 
and alphagram like '%I%' 
and alphagram like '%NN%' 
and alphagram like '%R%' 
and alphagram like '%TT%' 

... sera de retour 8 lignes (Entertain, instanter, intégrantes, intranets, ITINERANT, Nattering, RATTENING et TRANSITOIRE)

Ma question est la suivante: est-il un moyen plus efficace de le faire via SQL seulement?

Cela fonctionne très vite dans SQL Server mais assez lent dans SqlLite. Je réalise que les recherches% xxx% ne sont pas rapides.

+0

Y a-t-il une raison pour laquelle vous utilisez uniquement SQL au lieu d'une couche d'application? – JNK

+0

J'essaie de garder les choses simples, mais je vais probablement avoir cette route. – eponymous23

Répondre

0

Une idée est de le faire comme ça (pour une longueur de mot donné):

  • diviser le mot en caractères individuels (probablement en utilisant SUBSTRING() dans une boucle, mais une meilleure approche est probablement d'une valeur distincte ciblée SO question)

  • generate all permutations

  • PROFIT!

Bien que, en tant que commentateur dit, je vous conseille vivement de le faire en dehors de SQL, sauf si vous avez de très bonnes raisons de ne pas ou que vous faites tout cela pour remettre en question vos compétences.

2

Vous pouvez créer une sorte de colonne d'index pour chaque entrée contenant toutes les lettres du mot dans l'ordre alphabétique, puis les comparer. Chaque anagramme aura la même valeur d'index.

0

Le meilleur moyen que j'ai trouvé pour faire ceci est: J'ai créé des colonnes a ...z et analysé chaque mot et compté le nombre d'occurrences de la lettre donnée et le mettre sous la colonne suivante lorsque j'ai entré le mot pour déchiffrer j'ai compté chaque occurrence de chaque lettre pour ce mot et l'a comparé avec les mots dans le base de données Cela peut être un peu difficile à comprendre me faire savoir si vous avez besoin d'éclaircissements

0

Cette question est ancienne et je peut mal comprendre quelque chose, mais il semble que votre première demande pourrait être

select alphagram, word, definition 
from words 
where length = 8 
and alphagram = 'AEINNRTT' and word <> alphagram 

Cela fonctionne parce que tous les anagrammes de même longueur ont le même alphagram. Il utiliserait l'index sur alphagram et serait très rapide. Pour la longueur> 8 cas, il est plus difficile d'avoir un scénario facile, mais j'essaierais d'ajouter 26 colonnes à la table: alpha_a, alpha_b, .. contenant le numéro de chaque lettre de l'alphagram. Chacun peut avoir un index, puis vous recherchez

select alphagram, word, definition 
from words 
where length = 9 
and alpha_a >= 1 
and alpha_e >= 1 
and alpha_i >= 1 
and alpha_n >= 2 
and alpha_r >= 1 
and alpha_t >= 2 
Questions connexes