JAVA estructuras de datos y algoritmos: KMP

resumen

KMP algoritmo es una mejor cadena coincidente algoritmo, propuesto por DEKnuth, JHMorris y VRPratt, por lo que la gente llama Knuth - Morris - Pratt operación (denominado algoritmo KMP). El núcleo KMP algoritmo utilizando la información no coincide, para reducir al mínimo el número de match principal cadena de patrón de encordado para lograr el propósito del juego rápidamente. aplicación específico se ejecuta mediante una función next (), función de adaptación local de sí mismo contiene información de cadena de patrón. KMP algoritmo de tiempo complejidad de O (m + n).

breve introducción

cadena coincidente es el funcionamiento básico de la cadena, la forma más directa es atravesar la búsqueda retroceso completo, pero su alta complejidad, y como las personas buscan para que coincida con la eficiencia y optimizar el partido, igualando su complejidad se reduce gradualmente.
En este proceso, cuando la parte más importante de la KMP, se reducirá la complejidad del algoritmo original a O (n + m) en la que n, m es la longitud de las dos cadenas.

se detalla

El retroceso más directa

Inicio cadena coincidente desde la izquierda, si se produce el mismo sc j +1 y sus colegas, hasta que todos han atravesado el momento de volver a la p subíndice, si no es el mismo que el proceso de coincidencia llevó de nuevo a sc i.

public class Match_kmp {
    public static void main(String[] args) {
        System.out.println(indexOf("aaavbvdd","vbv"));
    }
    private static int indexOf(String s,String p){
        int i = 0;
        int sc = i;
        int j = 0;
        while (sc<s.length()){
            if(s.charAt(sc)==p.charAt(j)){
                j++;
                sc++;
                if(j==p.length()){
                    return i;
                }
            }else
            {
                i++;
                sc=i;
                j=0;
            }
        }
        return -1;
    }
}

Como resultado, el primer partido se devuelve el subíndice i

  • Este método de resolución de la complejidad alcanzó O (n * m), KMP algoritmo descrito a continuación.

partido KMP

diagrama

1571297220130

① coinciden izquierda a derecha, cuando i = 0, j = 0; si el mismo j ++, i ++, j si no Backtracking idéntica

② un partido diferente a la última vez retroceso tiempo si la violencia a juego i ++, por lo que j = 0;
pero antes de poder hacer uso de la cadena ha sido más de T, vuelta hacia atrás. Esto es más tiempo se reducirá la complejidad. j depende de la parte posterior al lado de la cadena coincidente T [Array]. A continuación la solución por debajo de dicha matriz en .Next = {0,0,0,0,2,2}
derecho cambio de gran pequeño = n e x t [ j ] = Tamaño de la derecha de la -Siguiente cadena coincidente [j]
por lo siguiente [5] = 2, el tamaño adecuado = 5-2, j en este momento es también dando marcha atrás
j = n e x t [ j 1 ] j = siguiente [j-1]
③ así, entonces j = 2, en comparación no son idénticas, dando marcha atrás j = 2-siguiente [j-

KMP

public class MatchKMP {
    public static void main(String[] args) {
        int ne[] =getNext("abcdabd");
        int res = kmp("ssdfgasdbababa","bababa",ne);
        System.out.println(res);
    }
    private static int kmp(String s,String t,int[] next){
        for (int i = 0,j=0;i<s.length();i++){
            while(j>0&&s.charAt(i)!=t.charAt(j)){
                j=next[j-1];
            }if(s.charAt(i)==t.charAt(j)){
                j++;
            }
            if(j==t.length()){
                return i-j+1;
            }
        }
        return 0;
    }
    private static int[] getNext(String t){
        int next[]=new int[t.length()];
        next[0]=0;
        for (int i = 1,j=0; i < t.length(); i++) {
            while (j>0&&t.charAt(j)!=t.charAt(i))
                j=next[j-1];
            if(t.charAt(i)==t.charAt(j))
                j++;
            next[i]=j;
        }
        return next;
    }
}

Solución de matriz siguiente

  • Prefijo es un conjunto de caracteres, excepto la última
  • Además de un primer conjunto de carácter sufijo del
    prefijo y el sufijo de abcabd calculado
    antes de que un sufijos de caracteres son 0
    ab y prefijo es [a] un sufijo [b] 0 es el mismo
    prefijo es abc [a, ab] sufijo es [bc, c] el mismo que el 0
    prefijo ABCA es [a, ab, abc] sufijo es [BCA, CA, a] 0
    abcab el prefijo [a, ab, abc, abca ] sufijo es [BCAB, cab, ab, b] máximo el mismo que ab siguiente [4] = 2
    prefijo abcabd es [a, ab, abc, abcb , abcabd]
    sufijo [bcabd, CABD, abd, bd , d] longitud total máxima o ab lo siguiente [ 5] = 2;
  private static int[] getNext(String t){
        int next[]=new int[t.length()];
        next[0]=0;
        for (int i = 1,j=0; i < t.length(); i++) {
            while (j>0&&t.charAt(j)!=t.charAt(i))
                j=next[j-1];
            if(t.charAt(i)==t.charAt(j))
                j++;
            next[i]=j;
        }
        return next;
    }

resumen

KMP algoritmo de aprendizaje que pasó mucho tiempo, sobre todo cuando se lee no se ha entendido. Más tarde, después de su propio dibujo, y al instante entender, las cosas todavía tienen que hacerlo.

referencia

Baidu Enciclopedia KMP algoritmo

Dibujo a mí mismo, y al instante entender, las cosas todavía tienen que hacerlo.

referencia

Baidu Enciclopedia KMP algoritmo

Blog de Ruan Yifeng cadena coincidente algoritmo KMP

Publicado 91 artículos originales · ganado elogios 9 · Vistas a 10000 +

Supongo que te gusta

Origin blog.csdn.net/WeDon_t/article/details/102611537
Recomendado
Clasificación