Comprensión del algoritmo KMP y código escrito a mano

algoritmo kmp

El algoritmo kmp es un algoritmo que compara si str1 (la longitud es n) contiene str2 (la longitud es s).

Pequeños consejos: el método de solución violenta es O (sn), pero mira el siguiente ejemplo:
[Error en la transferencia de la imagen del enlace externo. Es posible que el sitio de origen tenga un mecanismo de enlace anti-sanguijuela. Se recomienda guardar la imagen y subirla directamente (img-kwaUp18H-1609902020557) (A448D49100A84A0A849C310F28048565)]

ayd son diferentes, lo que indica que la cadena no coincide, si esSolución violenta, Se convertirá en lo siguiente.

[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuelas. Se recomienda guardar la imagen y subirla directamente (img-AhAgsDv5-1609902020563) (A01AEBDBA76B4332B6F973976649638B)]

Empareja de nuevo desde el principio, pero miraalgoritmo kmp¿Qué haremos después?
[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuela. Se recomienda guardar la imagen y subirla directamente (img-Rbya6R0y-1609902020569) (388ABA02FE214A8998B276175CFA3E22)]

¿Porqué es eso?

La esencia del algoritmo kmp es comprender las características de su propia búsqueda de cadenas y evitar coincidencias repetidas para acelerar el proceso de algoritmos violentos.

En la figura inicial
[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuelas. Se recomienda guardar la imagen y subirla directamente (img-B35m9ydF-1609902020573) (6DFDCF48CED44FE1B6CC6FCE9AA52F85)]

Tanto acac como acac se combinan con éxito y la cadena str2 cumple una característica antes de d

A . . . A A ... AA . . . Una
es decir, principio y al final son los mismos (A = ac) (... no =)

Por lo tanto, puede comprender mejor la imagen anterior. Part2 y part3 se han comparado con éxito, y también se comparan part2 y part1 (entendemos las características de str2). Naturalmente, no es necesario comparar part1 y part3. Puede saltar directamente a la siguiente imagen.
[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuela. Se recomienda guardar la imagen y subirla directamente (img-3q9zdtL7-1609902020582) (5000F41F7B784C17A2A983E8D9D003B4)]

Definir las características de la matriz str2-next

La siguiente matriz se refiere a cuando un bit de str1 no coincide con un bit de str2,¿A qué puntero j debería saltar?¿Qué?
Déjame darte algunas escenas, ¿a cuál deberías saltar?
[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuela. Se recomienda guardar la imagen y subirla directamente (img-gLKmYNgc-1609902020587) (7D38D9F8A6C849ECB0A6E51AE663C022)]

Aquí la cadena antes de d en str2 no cumple con las características de A ... A, así que pase a la siguiente figura
[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuelas. Se recomienda guardar la imagen y subirla directamente (img-1C8ppwkt-1609902020590) (3A337B369C0944778A23A5BFAB657A5D)]

(El puntero J salta a la posición 0, el puntero i no se mueve), luego siguiente [4] = 0 en nuestra siguiente matriz

¿Dónde saltas aquí?
[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuelas. Se recomienda guardar la imagen y subirla directamente (img-iplvHmus-1609902020593) (B742FC799BB141C59BDC2175BEBEDE2D)]

Encontramos que antes de que h en str2 satisfaga las características de A ... A, salte a la siguiente figura

[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuelas. Se recomienda guardar la imagen y subirla directamente (img-XVLeFYzt-1609902020607) (DCE3C5DCB989437C9C71D2F8E9E65B58)]

Es decir, el puntero i es diferente, el puntero j salta de la posición 6 a la posición 2, es decir, para esta cadena str2, next [6] = 4

¿Dónde saltas aquí? ? ?
[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuela. Se recomienda guardar la imagen y subirla directamente (img-sBzuVxCh-1609902020609) (BFF39C06E17544219D97C5814AEF26E9)]

Saltar a la imagen de abajo
[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuelas. Se recomienda guardar la imagen y subirla directamente (img-vTX79UQV-1609902020611) (2F204F26BD08423FA4F62F25ED9C2088)]

(I pointer +1, j pointer no se mueve, aquí definimos la siguiente matriz como -1, es decir, next [0] = - 1)

Mira la siguiente matriz a continuación
[Error en la transferencia de la imagen del enlace externo, el sitio de origen puede tener un mecanismo de enlace anti-sanguijuelas, se recomienda guardar la imagen y subirla directamente (img-a4m2kdwk-1609902020624) (B050060DF0DF4B949A614FF279C67CE2)]

  1. Si el bit 0 no es igual, el puntero i +1, el puntero j no se mueve, se establece en -1
  2. Si el primer lugar no es igual, mire la cadena antes de c, a, no cumple con las características de A ... A, y el puntero j salta a 0
  3. Si el segundo dígito no es igual, mire la cadena antes de a, ac, no cumple con las características de A ... A, y el puntero j salta a 0
  4. Si el tercer dígito no es igual, observe la cadena antes de c, aca, para cumplir con las características de A ... A, y el puntero j salta a la parte posterior de A, es decir, 1
  5. Si el cuarto dígito no es igual, mire la cadena antes de a, acac, y satisfaga las características de A ... A, el puntero j salta al siguiente dígito de A, que es 2
  6. Si la quinta posición no es igual, mire la cadena antes de f, acaca, y satisfaga las características de A ... A, el puntero j salta a la parte posterior de A (aca, A se superpone con A), es decir, 3.
  7. Si el sexto dígito no es igual, mire la cadena antes de g, acacaf, no cumple con las características de A ... A, el puntero j salta a 0

Código

public class main {
    
    
	//得到next数组
	//编写该函数代码是理解如何由next[i-1]得到next[i]
	//next[i-1]=t  代表前t位(0~t-1)  等于后面t位(到i-2位)
	//因此若s[t]==s[i-1]  则next[i]=t+1
	//否则最后一位不等代表不满足A...A的特点,直接为0
	public static int[] getnext(String s)
	{
    
    
		int[] next=new int[s.length()];
		next[0]=-1;
		for(int i=1;i<next.length;i++)
		{
    
    
			if(i==1)
			{
    
    
				next[1]=0;
			}
			else {
    
    
				if(s.charAt(next[i-1])==s.charAt(i-1))
				{
    
    
					next[i]=next[i-1]+1;
				}
				else {
    
    
					next[i]=0;
				}
			}
		}
		return next;
	}
	public static boolean kmpmatch(String s1,String s2)
	{
    
    
		int[] next=getnext(s2);
		int i=0,j=0;
		for(;i<s1.length();i++)
		{
    
    
			if(j==s2.length())
			{
    
    
				return true;
			}
			if(s1.charAt(i)==s2.charAt(j))
			{
    
    
			
				j+=1;
			}
			else
			{
    
    
				if(j==0)
				{
    
    
					i=i+1;
				}
				else {
    
    
					j=next[j];
				}
			}
		}
		return false;
		
	}
	
	
	public static void main(String[] args)
	{
    
    
		
		System.out.println(kmpmatch("adaddefg", "ac"));
	}
   
	

nextval

  1. Mejora de la siguiente matriz, fácil de entender

  2. La siguiente matriz representa la posición a la que saltará el puntero j. Si siguiente [a] = b, que no es igual a s2 [a], el puntero j salta de a a b. Si s2 [b] == s2 [a ], no esperará, sino que también saltará hacia adelante, por lo que podemos cambiar la siguiente matriz a la posición final del salto, que es nextval

  3. Por ejemplo
    [Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuelas. Se recomienda guardar la imagen y subirla directamente (img-BU89Zx63-1609902611201) (DB06AD98B1E741D6BD7476C8A95092D1)]

  4. Código

	public static int[] getnextval(String s)
	{
    
    
		int[] next=getnext(s);
		for(int i=0;i<next.length;i++)
		{
    
    
			if(s.charAt(i)==s.charAt(next[i]))
			{
    
    
				next[i]=next[next[i]];
			}
		}
		return next;
	}

aplicaciones kmp

Tema clásico 1: str1: "123456", hay muchas palabras rotativas, "123456", "23456,
" 345612 "... ¿
Determinar si str1 es una palabra rotativa de str2?

Extienda str1 a str1str1, y luego vea si str2 es una subcadena, y use kmp aquí.

Tema clásico 2: Pregunte si tree2 es un
subárbol del árbol 1. Debe estar completo y el subárbol contiene un nodo raíz completo:
[Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo de enlace anti-sanguijuelas. Se recomienda guardar la imagen y subirla directamente (img-dnRX3c4u-1609998685690) (43FA13799BE94B73AC917F4F59427878)]

Solución violenta:

public static class TreeNode {
    
    
	     int val;
	     TreeNode left;
	     TreeNode right;
	     TreeNode(int x) {
    
     val = x; }
	 }
	public static boolean ischildtree(TreeNode root1,TreeNode root2)
	{
    
    
		
		if(root1==null||root2==null)
		{
    
    
			return false;
		}
		if(issametree(root1, root2))
		{
    
    
			return true;
		}
		return ischildtree(root1.left, root2)||ischildtree(root1.right, root2);
		
	}
	
	
	public static boolean issametree(TreeNode root1,TreeNode root2)
	{
    
    
		if((root1==null&&root2!=null)||(root1!=null&&root2==null))
		{
    
    
			return false;
		}
		if(root1==null&&root2==null)
		{
    
    
			return true;
		}
		if(root1.val==root2.val)
		{
    
    
			return issametree(root1.left, root2.left)&&issametree(root1.right, root2.right);
		}
		else {
    
    
			return false;
		}
		
	}

La esencia también es una comparación de cadenas, cada árbol se llena en un árbol binario y se almacena en orden de matriz, y luego la "cadena detrás" se usa en el lado opuesto del algoritmo kmp, ¿es la subcadena anterior?

[Error en la transferencia de la imagen del enlace externo. Es posible que el sitio de origen tenga un mecanismo de enlace anti-sanguijuela. Se recomienda guardar la imagen y subirla directamente (img-ij3y9OY3-1609998685694) (F4D9753D86F54F4BAB9B44CD20A77E59)]

Supongo que te gusta

Origin blog.csdn.net/hch977/article/details/112260217
Recomendado
Clasificación