stringtranslate.com

Algoritmo de búsqueda de cadenas

En informática , los algoritmos de búsqueda de cadenas , a veces llamados algoritmos de coincidencia de cadenas , son una clase importante de algoritmos de cadenas que intentan encontrar un lugar donde se encuentran una o varias cadenas (también llamadas patrones) dentro de una cadena o texto más grande.

Un ejemplo básico de búsqueda de cadenas es cuando el patrón y el texto buscado son matrices de elementos de un alfabeto ( conjunto finito ) Σ. Σ puede ser un alfabeto de lenguaje humano, por ejemplo, las letras de la A a la Z y otras aplicaciones pueden usar un alfabeto binario (Σ = {0,1}) o un alfabeto de ADN (Σ = {A,C,G,T}) en bioinformática .

En la práctica, el método de un algoritmo de búsqueda de cadenas factible puede verse afectado por la codificación de la cadena. En particular, si se utiliza una codificación de ancho variable , puede resultar más lento encontrar el carácter N , y tal vez se necesite un tiempo proporcional a N. Esto puede ralentizar significativamente algunos algoritmos de búsqueda. Una de las muchas soluciones posibles es buscar la secuencia de unidades de código en su lugar, pero hacerlo puede producir coincidencias falsas a menos que la codificación esté diseñada específicamente para evitarlo. [ cita requerida ]

Descripción general

El caso más básico de búsqueda de cadenas implica una cadena (a menudo muy larga), a veces llamada pajar , y una cadena (a menudo muy corta), a veces llamada aguja . El objetivo es encontrar una o más apariciones de la aguja dentro del pajar. Por ejemplo, se podría buscar to dentro de:

Algunos libros son para saborearlos, otros para tragarlos y algunos para masticarlos y digerirlos.

Se podría solicitar la primera ocurrencia de "to", que es la cuarta palabra; o todas las ocurrencias, de las cuales hay 3; o la última, que es la quinta palabra desde el final.

Sin embargo, es muy común que se agreguen varias restricciones. Por ejemplo, se podría querer encontrar la palabra "needle" solo cuando esté compuesta por una (o más) palabras completas, tal vez definidas como aquellas que no tienen otras letras inmediatamente adyacentes a ninguno de los lados. En ese caso, una búsqueda de "hew" o "low" debería fallar para la oración del ejemplo anterior, aunque esas cadenas literales sí aparezcan.

Otro ejemplo común es el de la "normalización". Para muchos propósitos, una búsqueda de una frase como "ser" debería tener éxito incluso en lugares donde hay algo más entre "ser" y "ser":

Muchos sistemas de símbolos incluyen caracteres que son sinónimos (al menos para algunos propósitos):

Por último, en el caso de cadenas que representan lenguaje natural, intervienen aspectos del lenguaje en sí. Por ejemplo, se podría desear encontrar todas las apariciones de una "palabra" a pesar de que tenga otras formas de escribirla, prefijos o sufijos, etc.

Otro tipo de búsqueda más complejo es la búsqueda mediante expresiones regulares , en la que el usuario construye un patrón de caracteres u otros símbolos y cualquier coincidencia con el patrón debe satisfacer la búsqueda. Por ejemplo, para capturar tanto la palabra en inglés americano "color" como su equivalente británico "colour", en lugar de buscar dos cadenas literales diferentes, se podría utilizar una expresión regular como:

color

donde el "?" convencionalmente hace que el carácter precedente ("u") sea opcional.

Este artículo analiza principalmente algoritmos para los tipos más simples de búsqueda de cadenas.

Un problema similar introducido en el campo de la bioinformática y la genómica es el de la correspondencia exacta máxima (MEM). [1] Dadas dos cadenas, las MEM son subcadenas comunes que no se pueden extender hacia la izquierda o hacia la derecha sin causar un desajuste. [2]

Ejemplos de algoritmos de búsqueda

Búsqueda de cadenas ingenua

Una forma sencilla e ineficiente de ver dónde aparece una cadena dentro de otra es comprobar en cada índice, uno por uno. Primero, vemos si hay una copia de la aguja que comience en el primer carácter del pajar; si no, miramos para ver si hay una copia de la aguja que comience en el segundo carácter del pajar, y así sucesivamente. En el caso normal, solo tenemos que mirar uno o dos caracteres para cada posición incorrecta para ver que es una posición incorrecta, por lo que en el caso promedio, esto lleva O ( n + m ) pasos, donde n es la longitud del pajar y m es la longitud de la aguja; pero en el peor de los casos, buscar una cadena como "aaaab" en una cadena como "aaaaaaaaab", lleva O ( nm )

Búsqueda basada en autómatas de estados finitos

En este enfoque, se evita el retroceso mediante la construcción de un autómata finito determinista (DFA) que reconoce una cadena de búsqueda almacenada. Estos son costosos de construir (normalmente se crean mediante la construcción de conjuntos potenciados ), pero son muy rápidos de usar. Por ejemplo, el DFA que se muestra a la derecha reconoce la palabra "MOMMY". Este enfoque se suele generalizar en la práctica para buscar expresiones regulares arbitrarias .

Talones

Knuth–Morris–Pratt calcula un DFA que reconoce las entradas con la cadena que se va a buscar como sufijo; Boyer–Moore comienza la búsqueda desde el extremo de la aguja, por lo que normalmente puede saltar hacia adelante una longitud de aguja completa en cada paso. Baeza–Yates realiza un seguimiento de si los caracteres j anteriores fueron un prefijo de la cadena de búsqueda y, por lo tanto, es adaptable a la búsqueda de cadenas difusas . El algoritmo bitap es una aplicación del enfoque de Baeza–Yates.

Métodos de índice

Los algoritmos de búsqueda más rápidos preprocesan el texto. Después de construir un índice de subcadena , por ejemplo, un árbol de sufijos o una matriz de sufijos , se pueden encontrar rápidamente las ocurrencias de un patrón. Por ejemplo, se puede construir un árbol de sufijos a tiempo y se pueden encontrar todas las ocurrencias de un patrón a tiempo bajo el supuesto de que el alfabeto tiene un tamaño constante y todos los nodos internos en el árbol de sufijos saben qué hojas están debajo de ellos. Esto último se puede lograr ejecutando un algoritmo DFS desde la raíz del árbol de sufijos.

Otras variantes

Algunos métodos de búsqueda, como por ejemplo la búsqueda de trigramas , tienen como objetivo encontrar un índice de "proximidad" entre la cadena de búsqueda y el texto, en lugar de una "coincidencia/no coincidencia". A veces se las denomina búsquedas "difusas" .

Clasificación de algoritmos de búsqueda

Clasificación según una serie de patrones

Los distintos algoritmos se pueden clasificar según el número de patrones que utiliza cada uno.

Algoritmos de patrón único

En la siguiente compilación, m es la longitud del patrón, n la longitud del texto buscable y k = |Σ| es el tamaño del alfabeto.

1. ^ Los tiempos asintóticos se expresan utilizando la notación O, Ω y Θ .
2. ^ Se utiliza para implementar las funciones de búsqueda memmem y strstr en las bibliotecas estándar de C glibc [6] y musl [7] .
3. ^ Se puede ampliar para manejar coincidencias aproximadas de cadenas y conjuntos (potencialmente infinitos) de patrones representados como lenguajes regulares . [ cita requerida ]

El algoritmo de búsqueda de cadenas de Boyer-Moore ha sido el punto de referencia estándar para la literatura práctica de búsqueda de cadenas. [8]

Algoritmos que utilizan un conjunto finito de patrones

En la siguiente compilación, M es la longitud del patrón más largo, m su longitud total, n la longitud del texto buscable, o el número de ocurrencias.

Algoritmos que utilizan un número infinito de patrones

Naturalmente, en este caso los patrones no se pueden enumerar de forma finita. Se representan normalmente mediante una gramática regular o una expresión regular .

Clasificación mediante el uso de programas de preprocesamiento

Existen otros métodos de clasificación posibles. Uno de los más comunes utiliza el preprocesamiento como criterio principal.

Clasificación por estrategias de emparejamiento

Otro clasifica los algoritmos por su estrategia de emparejamiento: [12]

Véase también

Referencias

  1. ^ Kurtz, Stefan; Phillippy, Adam; Delcher, Arthur L; Smoot, Michael; Shumway, Martin; Antonescu, Corina; Salzberg, Steven L (2004). "Software versátil y abierto para comparar genomas grandes". Genome Biology . 5 (2): R12. doi : 10.1186/gb-2004-5-2-r12 . ISSN  1465-6906. PMC  395750 . PMID  14759262.
  2. ^ Khan, Zia; Bloom, Joshua S.; Kruglyak, Leonid; Singh, Mona (1 de julio de 2009). "Un algoritmo práctico para encontrar coincidencias exactas máximas en grandes conjuntos de datos de secuencias utilizando matrices de sufijos dispersos". Bioinformática . 25 (13): 1609–1616. doi :10.1093/bioinformatics/btp275. PMC 2732316 . PMID  19389736. 
  3. ^ Crochemore, Maxime; Perrin, Dominique (1 de julio de 1991). «Two-way string-matching» (PDF) . Revista de la ACM . 38 (3): 650–674. doi :10.1145/116825.116845. S2CID  15055316. Archivado (PDF) del original el 24 de noviembre de 2021. Consultado el 5 de abril de 2019 .
  4. ^ Navarro, Gonzalo; Raffinot, Mathieu (1998). "Un enfoque de bits paralelos a los autómatas de sufijos: comparación rápida de cadenas extendidas" (PDF) . Combinatorial Pattern Matching . Lecture Notes in Computer Science. Vol. 1448. Springer Berlin Heidelberg. págs. 14–33. doi :10.1007/bfb0030778. ISBN. 978-3-540-64739-3. Archivado (PDF) del original el 5 de enero de 2019. Consultado el 22 de noviembre de 2019 .
  5. ^ Fan, H.; Yao, N.; Ma, H. (diciembre de 2009). "Variantes rápidas del algoritmo de marcha hacia atrás de Oracle" (PDF) . 2009 Cuarta Conferencia Internacional sobre Computación en Internet para la Ciencia y la Ingeniería . pp. 56–59. doi :10.1109/ICICSE.2009.53. ISBN 978-1-4244-6754-9. S2CID  6073627. Archivado desde el original el 10 de mayo de 2022. Consultado el 22 de noviembre de 2019 .
  6. ^ "glibc/string/str-two-way.h". Archivado desde el original el 20 de septiembre de 2020. Consultado el 22 de marzo de 2022 .
  7. ^ "musl/src/string/memmem.c". Archivado desde el original el 1 de octubre de 2020 . Consultado el 23 de noviembre de 2019 .
  8. ^ Hume; Domingo (1991). "Búsqueda rápida de cadenas". Software: práctica y experiencia . 21 (11): 1221–1248. doi :10.1002/spe.4380211105. S2CID  5902579.
  9. ^ Commentz-Walter, Beate (1979). Un algoritmo de comparación de cadenas rápido en promedio (PDF) . Coloquio internacional sobre autómatas, lenguajes y programación . LNCS . Vol. 71. Graz, Austria: Springer. págs. 118–132. doi :10.1007/3-540-09510-1_10. ISBN 3-540-09510-1. Archivado desde el original (PDF) el 10 de octubre de 2017.
  10. ^ Melichar, Borivoj, Jan Holub y J. Polcar. Algoritmos de búsqueda de texto. Volumen I: Coincidencia de cadenas directas. Vol. 1. 2 vols., 2005. http://stringology.org/athens/TextSearchingAlgorithms/ Archivado el 4 de marzo de 2016 en Wayback Machine .
  11. ^ Riad Mokadem; Witold Litwin http://www.cse.scu.edu/~tschwarz/Papers/vldb07_final.pdf (2007), Búsqueda rápida de cadenas basada en nGram sobre datos codificados utilizando firmas algebraicas , 33.ª Conferencia internacional sobre bases de datos muy grandes (VLDB) {{citation}}: Enlace externo en |surname2=( ayuda )CS1 maint: numeric names: authors list (link)
  12. ^ Gonzalo Navarro; Mathieu Raffinot (2008), Cadenas de coincidencia de patrones flexibles: algoritmos prácticos de búsqueda en línea para textos y secuencias biológicas , Cambridge University Press, ISBN 978-0-521-03993-2

Enlaces externos