logo

El algoritmo de Knuth-Morris-Pratt (KMP)

Knuth-Morris y Pratt introducen un algoritmo de tiempo lineal para el problema de coincidencia de cadenas. Se logra un tiempo de coincidencia de O (n) evitando la comparación con un elemento de 'S' que haya estado involucrado previamente en comparación con algún elemento del patrón 'p' a emparejar. es decir, nunca se retrocede en la cadena 'S'

Componentes del algoritmo KMP:

1. La función de prefijo (Π): La función de prefijo, Π para un patrón, encapsula el conocimiento sobre cómo el patrón coincide con el cambio de sí mismo. Esta información se puede utilizar para evitar un cambio inútil del patrón 'p'. En otras palabras, esto permite evitar el retroceso de la cadena 'S'.

2. Los Partidos KMP: Con la cadena 'S', el patrón 'p' y la función de prefijo 'Π' como entradas, encuentre la aparición de 'p' en 'S' y devuelva el número de desplazamientos de 'p' después de los cuales se encuentran las apariciones.

La función de prefijo (Π)

El siguiente pseudocódigo calcula la función de prefijo, Π:

 <strong>COMPUTE- PREFIX- FUNCTION (P)</strong> 1. m &#x2190;length [P] //&apos;p&apos; pattern to be matched 2. &#x3A0; [1] &#x2190; 0 3. k &#x2190; 0 4. for q &#x2190; 2 to m 5. do while k &gt; 0 and P [k + 1] &#x2260; P [q] 6. do k &#x2190; &#x3A0; [k] 7. If P [k + 1] = P [q] 8. then k&#x2190; k + 1 9. &#x3A0; [q] &#x2190; k 10. Return &#x3A0; 

Análisis de tiempo de ejecución:

En el pseudocódigo anterior para calcular la función de prefijo, el bucle for del paso 4 al 10 se ejecuta 'm' veces. Los pasos 1 a 3 toman un tiempo constante. Por tanto, el tiempo de ejecución de la función de prefijo de cálculo es O (m).

Ejemplo: Calcule Π para el patrón 'p' siguiente:

¿Cuál es la diferencia entre un megabyte y un gigabyte?
Algoritmo de Knuth-Morris-Pratt

Solución:

 Initially: m = length [p] = 7 &#x3A0; [1] = 0 k = 0 
Algoritmo de Knuth-Morris-Pratt
Algoritmo de Knuth-Morris-Pratt

Después de iterar 6 veces, se completa el cálculo de la función de prefijo:

Algoritmo de Knuth-Morris-Pratt

El KMP coincide:

El KMP Matcher con el patrón 'p', la cadena 'S' y la función de prefijo 'Π' como entrada, encuentra una coincidencia de p en S. El siguiente pseudocódigo calcula el componente de coincidencia del algoritmo KMP:

 <strong>KMP-MATCHER (T, P)</strong> 1. n &#x2190; length [T] 2. m &#x2190; length [P] 3. &#x3A0;&#x2190; COMPUTE-PREFIX-FUNCTION (P) 4. q &#x2190; 0 // numbers of characters matched 5. for i &#x2190; 1 to n // scan S from left to right 6. do while q &gt; 0 and P [q + 1] &#x2260; T [i] 7. do q &#x2190; &#x3A0; [q] // next character does not match 8. If P [q + 1] = T [i] 9. then q &#x2190; q + 1 // next character matches 10. If q = m // is all of p matched? 11. then print &apos;Pattern occurs with shift&apos; i - m 12. q &#x2190; &#x3A0; [q] // look for the next match 

Análisis de tiempo de ejecución:

El bucle for que comienza en el paso 5 se ejecuta 'n' veces, es decir, tan largo como la longitud de la cadena 'S'. Dado que los pasos 1 a 4 toman tiempos constantes, el tiempo de ejecución está dominado por este para el ciclo. Por tanto, el tiempo de ejecución de la función coincidente es O (n).

Ejemplo: Dada una cadena 'T' y el patrón 'P' de la siguiente manera:

El algoritmo de Knuth-Morris-Pratt

Ejecutemos el algoritmo KMP para encontrar si 'P' ocurre en 'T'.

Para 'p' la función de prefijo, ? fue calculado previamente y es el siguiente:

El algoritmo de Knuth-Morris-Pratt

Solución:

 Initially: n = size of T = 15 m = size of P = 7 
Algoritmo de Knuth-Morris-Pratt
Algoritmo de Knuth-Morris-Pratt
Algoritmo de Knuth-Morris-Pratt
Algoritmo de Knuth-Morris-Pratt
Algoritmo de Knuth-Morris-Pratt
Algoritmo de Knuth-Morris-Pratt

Se ha descubierto que el patrón 'P' presenta complejidad en una cadena 'T'. El número total de turnos que tuvieron lugar para encontrar la coincidencia es i-m = 13 - 7 = 6 turnos.