2010-10-21 10 views
5

Dada la siguiente tabla de base de datos:¿Existe alguna forma mejor de encontrar anagramas utilizando SQL?

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

Donde:

  • 'alfagrama' es las letras de una palabra en orden alfabético (por ejemplo AEINNRTT es la alfagrama de INTRANET)
  • la clave primaria es 'palabra', y hay índices en alfagrama y longitud

He encontrado una forma de encontrar los anagramas de una cadena dada de letras s a través de SQL. Por ejemplo, para encontrar los anagramas de AEINNRTT esto funcionará:

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%' 

que devolverá 1 fila (por INTRANET)

y si quería incluir un número conocido de comodines, por ejemplo, cuántos las palabras están en INTRANET + en blanco (comodín) Solo tengo que cambiar la 'longitud' por el número total de letras + número de comodines

Por ej.

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%' 

... volverá 8 filas (entretener, instanter, integrantes, intranets, itinerante, Nattering, RATTENING y transitorio)

Mi pregunta es la siguiente: ¿hay una manera más eficiente de hacerlo a través de SQL solamente?

Esto funciona bastante rápido en SQLServer pero bastante lento en SqlLite. Me doy cuenta de que las búsquedas de% xxx% no son rápidas.

+0

¿Hay alguna razón por la que esté utilizando SQL solo en lugar de una capa de aplicación? – JNK

+0

Estoy tratando de mantener las cosas simples, pero es probable que tenga que hacer esa ruta. – eponymous23

Respuesta

0

Una idea es hacerlo de esta manera (para una longitud de palabra dada):

  • dividir la palabra en caracteres individuales (probablemente utilizando SUBSTRING() en un bucle, a través de un mejor enfoque es probablemente vale la pena una por separado dirigido cuestión de forma)

  • generate all permutations

  • beneficio!

Aunque, como dijo un comentarista, me encarecidamente que aconseja que haga que SQL fuera a menos que tenga muy buenas razones para no o si sólo está haciendo esto para desafiar sus habilidades.

2

Puede crear un tipo de columna de índice para cada entrada que tenga todas las letras de la palabra en orden alfabético y luego compararlas. Cada anagrama tendrá el mismo valor de índice.

0

La mejor manera en que me di cuenta de esto es: Creé columnas a ...z y analizó cada palabra y contó el número de ocurrencias de la letra dada y lo puso debajo de la columna correspondiente siguiente cuando ingresé la palabra para descifrar conté cada ocurrencia de cada letra para esa palabra y la comparé con las palabras en el base de datos de Esto puede ser un poco difícil de entender que me haga saber si necesita más aclaraciones

0

Esta pregunta es viejo y me puede malinterpretar algo, pero parece que su primera petición podría ser

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

Esto funciona porque todos los anagramas de igual longitud tienen el mismo alfagrama. Usaría el índice en alphagram y sería muy rápido.

para el caso de longitud> 8, es más difícil tener un escenario fácil, pero trataría de agregar 26 columnas a la tabla: alpha_a, alpha_b, .. que contiene el número de cada letra del alfagrama. Cada uno puede tener un índice y luego buscar

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 
Cuestiones relacionadas