in

Algoritmo KMP para búsqueda de patrones

gfg 200x200 min
Para cada palmadita de subpatrón[0..i] donde i = 0 a m-1, lps[i] almacena la longitud del prefijo adecuado máximo coincidente, que también es un sufijo del subpatrón pat[0..i].
   lps[i] = the longest proper prefix of pat[0..i] 
              which is also a suffix of pat[0..i]. 

Nota : lps[i] también podría definirse como el prefijo más largo, que también es el sufijo adecuado. Necesitamos usarlo correctamente en un lugar para asegurarnos de que no se considere la subcadena completa.

Examples of lps[] construction:
For the pattern “AAAA”, 
lps[] is [0, 1, 2, 3]

For the pattern “ABCDE”, 
lps[] is [0, 0, 0, 0, 0]

For the pattern “AABAACAABAA”, 
lps[] is [0, 1, 0, 1, 2, 0, 1, 2, 3, 4, 5]

For the pattern “AAACAAAAAC”, 
lps[] is [0, 1, 2, 0, 1, 2, 3, 3, 3, 4] 

For the pattern “AAABAAA”, 
lps[] is [0, 1, 2, 0, 1, 2, 3]

Algoritmo de búsqueda:
A diferencia del algoritmo ingenuo, donde deslizamos el patrón en uno y comparamos todos los caracteres en cada turno, usamos un valor de lps[] para decidir los siguientes caracteres que se combinarán. La idea es no coincidir con un personaje que sabemos que coincidirá de todos modos.

Cómo usar lps[] para decidir las siguientes posiciones (o para saber una cantidad de caracteres que se deben omitir)?

  • Empezamos la comparación de pat[j] con j = 0 con caracteres de la ventana de texto actual.
  • Seguimos haciendo coincidir caracteres txt[i] y palmadita[j] y sigue aumentando i y j mientras palmaditas[j] y txt[i] guardar pareo.
  • Cuando vemos un discordancia
    • Sabemos que los personajes acarician[0..j-1] coincidir con txt[i-j…i-1] (Tenga en cuenta que j comienza con 0 y lo incrementa solo cuando hay una coincidencia).
    • También sabemos (de la definición anterior) que lps[j-1] es recuento de caracteres de pat[0…j-1] que son tanto prefijo y sufijo adecuados.
    • De los dos puntos anteriores, podemos concluir que no necesitamos hacer coincidir estos lps[j-1] caracteres con txt[i-j…i-1] porque sabemos que estos personajes coincidirán de todos modos. Consideremos el ejemplo anterior para entender esto.
txt[] = "AAAAABAAABA" 
pat[] = "AAAA"
lps[] = {0, 1, 2, 3} 

i = 0, j = 0
txt[] = "AAAAABAAABA" 
pat[] = "AAAA"
txt[i] and pat[j] match, do i++, j++

i = 1, j = 1
txt[] = "AAAAABAAABA" 
pat[] = "AAAA"
txt[i] and pat[j] match, do i++, j++

i = 2, j = 2
txt[] = "AAAAABAAABA" 
pat[] = "AAAA"
pat[i] and pat[j] match, do i++, j++

i = 3, j = 3
txt[] = "AAAAABAAABA" 
pat[] = "AAAA"
txt[i] and pat[j] match, do i++, j++

i = 4, j = 4
Since j == M, print pattern found and reset j,
j = lps[j-1] = lps[3] = 3

Here unlike Naive algorithm, we do not match first three 
characters of this window. Value of lps[j-1] (in above 
step) gave us index of next character to match.
i = 4, j = 3
txt[] = "AAAAABAAABA" 
pat[] =  "AAAA"
txt[i] and pat[j] match, do i++, j++

i = 5, j = 4
Since j == M, print pattern found and reset j,
j = lps[j-1] = lps[3] = 3

Again unlike Naive algorithm, we do not match first three 
characters of this window. Value of lps[j-1] (in above 
step) gave us index of next character to match.
i = 5, j = 3
txt[] = "AAAAABAAABA" 
pat[] =   "AAAA"
txt[i] and pat[j] do NOT match and j > 0, change only j
j = lps[j-1] = lps[2] = 2

i = 5, j = 2
txt[] = "AAAAABAAABA" 
pat[] =    "AAAA"
txt[i] and pat[j] do NOT match and j > 0, change only j
j = lps[j-1] = lps[1] = 1 

i = 5, j = 1
txt[] = "AAAAABAAABA" 
pat[] =     "AAAA"
txt[i] and pat[j] do NOT match and j > 0, change only j
j = lps[j-1] = lps[0] = 0

i = 5, j = 0
txt[] = "AAAAABAAABA" 
pat[] =      "AAAA"
txt[i] and pat[j] do NOT match and j is 0, we do i++.

i = 6, j = 0
txt[] = "AAAAABAAABA" 
pat[] =       "AAAA"
txt[i] and pat[j] match, do i++ and j++

i = 7, j = 1
txt[] = "AAAAABAAABA" 
pat[] =       "AAAA"
txt[i] and pat[j] match, do i++ and j++

We continue this way...

C ++

#include <bits/stdc++.h>

 

void computeLPSArray(char* pat, int M, int* lps);

 

void KMPSearch(char* pat, char* txt)

{

    int M = strlen(pat);

    int N = strlen(txt);

 

    

    

    int lps[M];

 

    

    computeLPSArray(pat, M, lps);

 

    int i = 0;

    int j = 0;

    while (i < N) {

        if (pat[j] == txt[i]) {

            j++;

            i++;

        }

 

        if (j == M) {

            printf("Found pattern at index %d ", i - j);

            j = lps[j - 1];

        }

 

        

        else if (i < N && pat[j] != txt[i]) {

            

            

            if (j != 0)

                j = lps[j - 1];

            else

                i = i + 1;

        }

    }

}

 

void computeLPSArray(char* pat, int M, int* lps)

{

    

    int len = 0;

 

    lps[0] = 0;

 

    

    int i = 1;

    while (i < M) {

        if (pat[i] == pat[len]) {

            len++;

            lps[i] = len;

            i++;

        }

        else

        {

            

            

            

            if (len != 0) {

                len = lps[len - 1];

 

                

                

            }

            else

            {

                lps[i] = 0;

                i++;

            }

        }

    }

}

 

int main()

{

    char txt[] = "ABABDABACDABABCABAB";

    char pat[] = "ABABCABAB";

    KMPSearch(pat, txt);

    return 0;

}

Java

 

class KMP_String_Matching {

    void KMPSearch(String pat, String txt)

    {

        int M = pat.length();

        int N = txt.length();

 

        

        

        int lps[] = new int[M];

        int j = 0;

 

        

        

        computeLPSArray(pat, M, lps);

 

        int i = 0;

        while (i < N) {

            if (pat.charAt(j) == txt.charAt(i)) {

                j++;

                i++;

            }

            if (j == M) {

                System.out.println("Found pattern "

                                   + "at index " + (i - j));

                j = lps[j - 1];

            }

 

            

            else if (i < N && pat.charAt(j) != txt.charAt(i)) {

                

                

                if (j != 0)

                    j = lps[j - 1];

                else

                    i = i + 1;

            }

        }

    }

 

    void computeLPSArray(String pat, int M, int lps[])

    {

        

        int len = 0;

        int i = 1;

        lps[0] = 0;

 

        

        while (i < M) {

            if (pat.charAt(i) == pat.charAt(len)) {

                len++;

                lps[i] = len;

                i++;

            }

            else

            {

                

                

                

                if (len != 0) {

                    len = lps[len - 1];

 

                    

                    

                }

                else

                {

                    lps[i] = len;

                    i++;

                }

            }

        }

    }

 

    

    public static void main(String args[])

    {

        String txt = "ABABDABACDABABCABAB";

        String pat = "ABABCABAB";

        new KMP_String_Matching().KMPSearch(pat, txt);

    }

}

Pitón

def KMPSearch(pat, txt):

    M = len(pat)

    N = len(txt)

 

    

    

    lps = [0]*M

    j = 0

 

    

    computeLPSArray(pat, M, lps)

 

    i = 0

    while i < N:

        if pat[j] == txt[i]:

            i += 1

            j += 1

 

        if j == M:

            print ("Found pattern at index " + str(i-j))

            j = lps[j-1]

 

        

        elif i < N and pat[j] != txt[i]:

            

            

            if j != 0:

                j = lps[j-1]

            else:

                i += 1

 

def computeLPSArray(pat, M, lps):

    len = 0

 

    lps[0]

    i = 1

 

    

    while i < M:

        if pat[i]== palmadita[len]:

            len += 1

            lps[i] = len

            i += 1

        else:

            

            

            

            if len != 0:

                len = lps[len-1]

 

                

            else:

                lps[i] = 0

                i += 1

 

txt = "ABABDABACDABABCABAB"

pat = "ABABCABAB"

KMPSearch(pat, txt)

 

C#

using System;

 

class GFG {

 

    void KMPSearch(string pat, string txt)

    {

        int M = pat.Length;

        int N = txt.Length;

 

        

        

        int[] lps = new int[M];

        int j = 0;

 

        

        

        computeLPSArray(pat, M, lps);

 

        int i = 0;

        while (i < N) {

            if (pat[j] == txt[i]) {

                j++;

                i++;

            }

            if (j == M) {

                Console.Write("Found pattern "

                              + "at index " + (i - j));

                j = lps[j - 1];

            }

 

            

            else if (i < N && pat[j] != txt[i]) {

                

                

                if (j != 0)

                    j = lps[j - 1];

                else

                    i = i + 1;

            }

        }

    }

 

    void computeLPSArray(string pat, int M, int[] lps)

    {

        

        int len = 0;

        int i = 1;

        lps[0] = 0;

 

        

        while (i < M) {

            if (pat[i] == pat[len]) {

                len++;

                lps[i] = len;

                i++;

            }

            else

            {

                

                

                

                if (len != 0) {

                    len = lps[len - 1];

 

                    

                    

                }

                else

                {

                    lps[i] = len;

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

apple touch icon@2

Borde de fuente CSS? – Desbordamiento de pila

650px Kraus sink

Tipos de montaje de grifos de cocina: diferencia y comparación