A lg oritmo or itmo de bús queda y su s u efici efi ci encia enc ia de c adena K nuth-Morr nuth-Mo rr i s -P ratt. Por: José Avendaño, Jonathan Muñoz y Kendall Kant
¿Qué es? Es un algoritmo de búsqueda de subcadenas simple y por lo tanto su objetivo es buscar la existencia de una subcadena dentro de una cadena. Para ello utiliza información basada en los fallos previos, aprovechando la información que la p ropia palabra a buscar contiene de sí (sobre ella se precalcula una tabla de valores), para determinar donde podría darse la siguiente existencia, sin necesidad de analizar más de 1 vez los caracteres de la cadena donde se busca.
Historia: El algoritmo de búsqueda de cadenas Knuth-Morris-Pratt (KMP) busca la aparición de una palabra P dentro de una “cadena de texto” principal C. Inventado por Knuth y Pratt e independientemente por J. H. Morris en 1977, pero los tres lo publicaron en conjunto.
Descripción del Algoritmo KMP: El algoritmo KMP, trata de localizar la posición de comienzo de una cadena, dentro de otra. Antes que nada con la cadena a localizar se precalcula una tabla de saltos (conocida como tabla de fallos) que después al examinar entre si las cadenas se utiliza para hacer saltos cuando se localiza un fallo.
¿Dónde se aplica el algoritmo KMP? Medicina: Búsqueda de cadena de aminoácidos en las cadenas de proteínas. Programación: En los antivirus, búsqueda de cadena de caracteres de la firma de algún virus. En administración de un chat interno de una empresa (buscar malas palabras).
Algoritmo de búsqueda de KMP:
Pseudocódigo
Algoritmo BúsquedaKMP : Entrada: un array de caracteres, T (el texto donde se busca) un array de caracteres, P (la palabra/s que se busca)
Salida: un entero que expresa la posición en T en la cual se encontró P. (nota: opcionalmente puede convenir devolver un entero con signo).
Definición de variables: un entero, k ← 0 (puntero de examen en T) un entero, i ← 0 (la posición del carácter actual en P, y avance
relativo respecto de k, para T) un array de enteros, F (la tabla de fallo, calculada a continuación, o en otra parte)
Si tamaño de T es mayor o igual que tamaño de P entonces Precalcular TablaKMP(P,F) Mientras k + i es menor que la longitud de T, hacer Si P[i] = T[k + i] entonces Si i es igual a la longitud de P - 1 entonces Devolver k Fin si Asignar i ← i + 1 Si no entonces Asignar k ← k + i - F[i] Si i es mayor que 0 entonces Asignar i ← F[i] Fin si Fin si Repetir Fin si (si se alcanza este punto, se buscó en todas las T sin éxito)
Devolver longitud de T, ó si se usa una variable con signo, devolver -1
Leng uaje C ++
int busquedaKMP(char *p, char *a) { int i,j, M=strlen(p), N=strlen(a); inicprox(p); for(i=0, j=0;j
Algoritmo para el llenado de la tabla:
Pseudocódigo
Algoritmo TablaKMP : Entrada: un array de caracteres, P (la palabra/texto que va a ser analizada) un array de enteros, F (la tabla de fallos a rellenar) debe tener el mismo tamaño que P.
Salida: nada, no devuelve valores( pero por referencia, devuelve la tabla rellenada)
variables que se usan: un entero, pos ← 2 (la posición actual donde se está
calculando F) un entero, cnd ← 0 (el índice en P del siguiente carácter del
actual candidato en la subcadena) (algunos valores se fijan con determinado valor, y por tanto no están sujetos a lo que cabría esperar del algoritmo, esto se explica más arriba, en el apartado de la descripción)
asignar F[0] ← -1, F[1] ← 0 Hacer mientras pos sea menor o igual que el tamaño de P: (caso 1º: siguiente candidato coincidente en la cadena)
Si P[pos - 1] = P[cnd] entonces Asignar cnd ← cnd + 1, F[pos] ← cnd, pos ← pos + 1 (caso 2º: cuando empieza a fallar las coincidencias consecutivas, entonces asignamos un valor ya conocido la 1ª vez)
Pero si cnd > 0 entonces Asignar cnd ← F[cnd] (caso 3º: no se halló candidatos coincidentes (otra vez))
Y si no entonces Asignar F[pos] ← 0, pos ← pos + 1 Fin si Repetir
Leng uaje C ++
inicprox(char *p) { int i, j, M=strlen(p); prox[0]=-1; for(i=0, j=-1; i=0) && (p[i]!=p[j])) j=prox[j]; }