algoritmo KMP utiliza comúnmente algoritmos programador diez


Aquí Insertar imagen Descripción

Este artículo es el primero programadores algoritmo utilizado comúnmente en los diez primeros, detrás del algoritmo se resumen en el blog! ! !

A. Escenarios

 problema cadena coincidente:

  1. Hay una cadena str1 = "" Silicon Valley Silicon Valley, sin embargo todavía de Silicon Valley sin embargo aún todavía Silicon Valley hola "", y una subcadena str2 = "sin embargo todavía Silicon Valley que."
  2. Para determinar si contiene str2 ahora str1, si está presente, se devuelve la posición de la primera aparición, si no, se devuelve -1

II. La violencia algoritmo de coincidencia

2.1 Análisis de las ideas

Si la idea de coincidencia de la violencia, y suponiendo ahora str1 adaptada a la posición i, j emparejado subcadena posición str2, se encuentran:

  1. Si el carácter actual coincide con el éxito (es decir str1 [i] == str2 [j ]), entonces ++ i, J ++ , continúa para que coincida con el siguiente carácter
  2. Si una falta de coincidencia (es decir str1 [i] = str2 [j !]), De modo que I = I - (J -. 1) , J = 0 . Cuando el fallo correspondiente a cada partido, i retroceso, j se establece en 0.
  3. La solución es el uso de la violencia, entonces habrá una gran cantidad de retroceso , un tiempo para mover uno, si no coinciden, a continuación, pasar a la siguiente juez, perdiendo mucho tiempo. (No es posible!)

2.2 aplicación de código

package algorithm;

/**
 * @author 陌生人
 * @version V1.0
 * @Title:
 * @Package
 * @Description: (用一句话描述该文件做什么)
 * @date:
 */
public class ViolenceMatch {
   public static void main(String[] args) {
      String str1 = "硅硅谷 尚硅谷你尚硅 尚硅谷你尚硅谷你尚硅你好";
      String str2 = "尚硅谷你尚硅";
      int index = violenceMatch(str1, str2);
      System.out.println("index=" + index);
   }

   public static int violenceMatch(String s1, String s2) {
      char[] c1 = s1.toCharArray();
      char[] c2 = s2.toCharArray();
      int i = 0;
      int j = 0;
      int s1len = s1.length();
      int s2len = s2.length();
      while (i < s1len && j < s2len) {

         if (c1[i] == c2[j]) {
            i++;
            j++;
         } else {
            i = i - j + 1;
            j = 0;
         }
      }
      if (j == s2len) {
         return i - j;
      } else {
         return -1;
      }

   }
}

III. Algoritmo introdujo

  1. KMP es un modelo para resolver la cadena en la cadena de texto que se hayan producido, en caso dado, la ubicación del algoritmo clásico temprano
  2. Knuth-Morris-Pratt algoritmo de búsqueda de cadenas, se refiere como "el algoritmo KMP", a menudo se utiliza para encontrar la posición de un Aparece cadena de patrón P en una cadena de texto S, el algoritmo de Donald Knuth, Vaughan Pratt, James H. Morris en tres en 1977, publicado conjuntamente, por lo que optó por las tres personas que llevan el nombre del algoritmo.
  3. Antes de que el algoritmo se determina usando el método de KMP través de la información a través de una matriz siguiente, la longitud de la subsecuencia común más larga almacena antes y después de la cadena patrón, cada atrás en el tiempo por la matriz para encontrar el siguiente, sobre la parte frontal de la ubicación coincidente, eliminando la gran cantidad de cálculo tiempo

aplicación óptima Cuatro algoritmo .KMP

4.1 problema de la concordancia de cadena

problema de coincidencia de cadenas:

  1. Una cadena str1 = "BBC ABCDAB ABCDABCDABDE", y una subcadena str2 = "ABCDABD"
  2. Para determinar si contiene str2 ahora str1, si está presente, se devuelve la posición de la primera aparición, si no, se devuelve -1
  3. Requisitos: KMP algoritmo utilizando la sentencia completa, simplemente no pueden utilizar la violencia algoritmo de coincidencia.

4.2 Análisis de las ideas gráficas

Por ejemplo, una cadena Str1 = "BBC ABCDAB ABCDABCDABDE", se determina, que contiene otra cadena Str2 = "ABCDABD"?

  1. En primer lugar, Str1 primer carácter y el primer carácter de Str2 para comparar, no, mover hacia atrás una palabra clave## 4.3 aplicación de código

  2. Repita el paso o no, y en aquel entonces movido

  3. Se repite hasta Str1 tiene un personaje con el primer carácter se reúne Str2
    4.

  4. A continuación, comparar la secuencia y el siguiente carácter en el término de búsqueda o en línea.
    Aquí Insertar imagen Descripción

  5. Str1 se han encontrado con un personaje con Str2 correspondientes caracteres no coincidan.
    Aquí Insertar imagen Descripción

  6. En este momento, esperamos que continúe para atravesar el siguiente carácter Str1 Repita el paso 1. (De hecho, es muy poco aconsejable, porque el BCD han comparado, no hay necesidad de hacer un trabajo repetitivo, un hecho básico es que cuando el espacio y D no coinciden, que realmente saben los seis primeros caracteres son "ABCDAB". la idea del algoritmo KMP es tratar de utilizar esta información conocida, no a la posición "Buscar" para retroceder han comparado la posición, que continúa moviéndose hacia atrás, mejorando así la eficiencia.)

Aquí Insertar imagen Descripción

  1. ¿Cómo se limite a repetir los pasos omitidos? Str2 puede calcular una "tabla de coincidencias parciales"

Aquí Insertar imagen Descripción

  1. D es conocida espacio y no coincide con los seis primeros caracteres partido "ABCDAB". Look-up tabla se puede ver, el último juego de caracteres B correspondiente a un "valor parcial coincidencia" es 2, por lo que el número de bits calculada por el movimiento hacia atrás de la siguiente ecuación:
    número de bits de desplazamiento = número de caracteres emparejados - una porción correspondiente al valor de coincidencia
    como 6 - 2 es igual a 4, por lo que el movimiento hacia atrás de cuatro término de búsqueda.
  2. Debido a que los espacios y C no coinciden con el término de búsqueda continuará hacia atrás. En este caso, el número de caracteres emparejado es 2 ( "AB"), que corresponde a la "parte de la valor coincidente" es 0. Por lo tanto, el número de bits de desplazamiento = 2--0, el resultado es 2, luego dos búsqueda Canal de desplazamiento hacia atrás.
    Aquí Insertar imagen Descripción

10. Dado que el espacio no se corresponde con la A, después de un cambio continuo.
Aquí Insertar imagen Descripción

  1. comparación bit a bit, hasta el descubrimiento de C y D no se correspondan. Entonces, el número de bits de desplazamiento = 6--2, palabra de búsqueda continúa moviéndose hacia atrás 4.
    Aquí Insertar imagen Descripción

  2. comparación bit a bit, hasta que el último bit de términos de búsqueda, coincidencia exacta, por lo que se complete la búsqueda. Si también desea continuar la búsqueda (es decir, encontrar toda la correspondencia), mediana = 7-0 en movimiento, y luego buscar la palabra para retroceder 7, no se repetirá aquí.
    Aquí Insertar imagen Descripción

  3. Lo que introducir la "tabla de coincidencias parciales" describe cómo producir un prefijo, sufijo
    Aquí Insertar imagen Descripción

"Valor de coincidencia parcial" es la longitud de "prefijo" y "sufijo" de los elementos comunes más largas.
En "ABCDABD" un ejemplo,
"A" prefijo y sufijo son conjunto vacío, la longitud de los elementos comunes es 0;
prefijo "AB" es [A], el sufijo es [B], la longitud de los elementos comunes es 0;
" ABC "prefijo es [a, AB], el sufijo [BC, C], la longitud de los elementos comunes de 0;
" prefijo ABCD "es [a, AB, ABC], el sufijo [BCD, CD, D], un total de longitud de los elementos es 0;
prefijo "ABCDA" es [a, AB, ABC, ABCD ], el sufijo [BCDA, CDA, DA, un ], elementos comunes de "a", la longitud 1;
prefijo "ABCDAB" de es [a, AB, ABC, ABCD , ABCDA], el sufijo [BCDAB, CDAB, DAB, AB , B], los elementos comunes de "AB", una longitud de 2;
el prefijo "ABCDABD" es [a, AB, ABC , ABCD, ABCDA, ABCDAB], el sufijo [BCDABD, CDABD, DABD, ABD , BD, D], 0 es la longitud de los elementos comunes.

  1. "Coincidencia parcial", en esencia, a veces, se repetirá la línea de cabeza y la cola.
    Por ejemplo, "ABCDAB" en dos "AB", que "valor coincidente parcial" es 2 (longitud "AB") es. Cuando se mueve la palabra de búsqueda, el primer "AB" retroceso 4 (cadena de longitud - valor parcial partido), se puede llegar a la segunda posición "AB".
    Aquí Insertar imagen Descripción

la implementación del código

package algorithm;

import java.util.Arrays;

/**
 * @author 陌生人
 * @version V1.0
 * @Title:
 * @Package
 * @Description: (用一句话描述该文件做什么)
 * @date:
 */
public class KMPAlgorithm {
   public static void main(String[] args) {
      String str1 = "BBCABCDABABCDABCDABDE";
      String str2 = "ABCDABD";
//Stringstr2="BBC";
      int[] next = kmpNext("ABCDABD");//[0,1,2,0]
      System.out.println("next=" + Arrays.toString(next));
      int index = kmpSearch(str1, str2, next);
      System.out.println("index=" + index);//15了

   }

   public static int kmpSearch(String str1, String str2, int[] next) {
      //遍历
      for (int i = 0, j = 0; i < str1.length(); i++) {
         //需要处理
         // str1.charAt(i)!=str2.charAt(j),去调整j的大小
         // KMP算法核心点,可以验证...
         while (j > 0 && str1.charAt(i) != str2.charAt(j)) {
            j = next[j - 1];
         }

         if (str1.charAt(i) == str2.charAt(j)) {
            j++;
         }
         if (j == str2.length()) {//找到了//j=3i
            return i - j + 1;
         }
      }
      return -1;
   }

   //获取到一个字符串(子串)的部分匹配值表
   public static int[] kmpNext(String dest) {
      //创建一个next数组保存部分匹配值
      int[] next = new int[dest.length()];
      next[0] = 0;
      //如果字符串是长度为1部分匹配值就是0
      for (int i = 1, j = 0; i < dest.length(); i++) {
         //当dest.charAt(i)!=dest.charAt(j),我们需要从next[j-1]获取新的j
         // 直到我们发现有dest.charAt(i)==dest.charAt(j)成立才退出
         // 这时kmp算法的核心点
         while (j > 0 && dest.charAt(i) != dest.charAt(j)) {
            j = next[j - 1];
         }

         //当dest.charAt(i)==dest.charAt(j)满足时,部分匹配值就是+1
         if (dest.charAt(i) == dest.charAt(j)) {
            j++;
         }
         next[i] = j;
      }
      return next;
   }
}

Largo camino por recorrer, JAVA como socios! ! !

Publicado 23 artículos originales · ganado elogios 71 · vistas 5747

Supongo que te gusta

Origin blog.csdn.net/qq_43688587/article/details/105153345
Recomendado
Clasificación