2011-06-27 11 views
6

Así que sí, leí acerca de cómo se puede usar la distancia de edición entre cadenas para decidir cómo "cerrar" dos cadenas entre sí. Este algoritmo, implementado como un problema dinámico toma O (mn) el tiempo, donde myn son las longitudes del texto y el patrón, respectivamente. Entonces, si tengo que unir una cuerda con otras 5000 cuerdas, tomará MUCHO tiempo, lo cual en mi aplicación simplemente no es aceptable. ¿Hay una solución más rápida que pueda implementarse? No me importa cambiar el espacio de almacenamiento por tiempo.Búsqueda aproximada contra una lista de cadenas

He visto una aplicación llamada "Swype" en Android, que hace algo similar. Busca su consulta en su propia base de datos y sugiere resultados. ¿Cómo funciona eso tan rápido?

Nota: No sugiera marcos como Lucene, porque no puedo ejecutarlos en J2ME.

+0

¿Esto es para tipear las correcciones? ¿Estás seguro de que necesitas algo más rápido que la distancia de Levenshtein? 5000 no suena tan mal si son palabras cortas del diccionario. –

+0

Esto es básicamente para buscar un nombre de artículo (consulta de usuario) en una lista de artículos que se rellenan previamente. Ahora, dado que el usuario puede ingresar consultas incorrectas, la búsqueda debe sugerir la coincidencia más cercana o una "no coincidencia" si no se encuentra ninguna. – Gooner

Respuesta

2

de splix es buena. Como otra opción (para grandes conjuntos de cuerda), es posible que desee considerar el uso de una representación de n-gramas:

http://en.wikipedia.org/wiki/N-gram

Éstos se utilizan para la coincidencia de patrones aproximados en una gran cantidad de paquetes de bases de datos, ya que son rápidos y fácil de implementar usando metodologías de indexación convencionales.

1

Hemos usado http://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_string_matching_algorithm para casi lo mismo, y funcionó bien para nosotros.

Hay pocas implementaciones de Java de la misma, se pueden encontrar en la web

PS también se puede comprobar otros algoritmos cadena de equiparación: Respuesta http://en.wikipedia.org/wiki/String_searching_algorithm

+0

splix, por "nosotros" ¿quieres decir Swype? – Gooner

+0

no, me refiero a otra empresa, donde trabajé antes de –

+0

Parece que el algoritmo de Aho coincide con muchas palabras clave en un texto. En mi caso, tengo una palabra clave contra muchos textos. Entonces, ¿el proceso simplemente se invierte? Es decir, ¿todo el texto que tengo ahora se convierte en palabras clave y las palabras clave individuales se convierten en el texto? – Gooner

0

También es una cuestión de cómo definir "cerrar". Si no insiste en lo escrito, pero también funcionaría, podría sugerir soundex. Es un algoritmo muy rápido para ver si 2 palabras tienen un cierre fonético.

+0

Digo "cerrar" en el contexto del algoritmo antes mencionado. Soundex suena realmente genial. Lo echaré un vistazo. – Gooner

1

Realmente depende de los textos que está comparando. A continuación, presento dos enfoques de aceleración dentro del marco de edición-distancia original.

Una vez tuvimos la misma tarea en la que combinamos una secuencia de palabras corta (algo así como 10-30 caracteres) frente a un diccionario de> 300k frases cortas (también 10-30 caracteres cada una). En este caso, el siguiente enfoque nos salvó un montón de tiempo:

  • tipo el diccionario de cadenas de destino (esto se tiene que hacer sólo una vez)
  • cuando se genera la tabla n * m de cuerda i que pueda reutilice la tabla de la cadena i-1 ya que la mayoría de las líneas son comunes.

E.g. si tiene las dos cadenas "list of strings" y siguiente "list of words" puede reutilizar las primeras 8 líneas de su tabla y solo tiene que volver a calcular 5 (ambas cadenas tienen 8 caracteres en común). De esta forma, ahorramos hasta el 70-80% del tiempo de ejecución con solo pequeños cambios en nuestro código.

Si en cambio tiene pocos textos largos, el primer enfoque no le ahorrará mucho. Pero en este caso, usted espera que solo unas pocas entradas tengan una pequeña distancia de edición, mientras que las demás tienen una gran distancia. Como la tabla n * m es un tanto monótona en cada dirección (es decir, el mínimo de cada línea es monotónico, así como para cada columna), puede detener el cálculo una vez que alcanza un umbral preestablecido.Incluso puede guardar los resultados intermedios y "reiniciar" el cálculo (con un límite superior) si no encuentra una solución dentro de su umbral inicial.

+0

Esas son algunas de las optimizaciones más geniales con el reutilización de la tabla allí. Mi conjunto de datos está ordenado lexicográficamente, pero creo que la reutilización de la tabla de cadena (i-1) depende en gran medida del tipo de conjunto de datos. No sé exactamente cuánto me ayudará eso. Tengo la intención de mantener el umbral en un valor definido que probablemente conoceré mejor probando en varios valores (es decir, qué valor me sienta mejor). Votaré su respuesta, ya que realmente me gusta la reutilización del concepto de tabla. – Gooner

Cuestiones relacionadas