KMP【知识点】

#include<iostream>
#include<algorithm>
#include<stdio.h>
using namespace std;
const int maxn = 1e6+20;
int nxt[maxn];
int n,m;//n母串,m子串
int s[maxn];//母串
int t[maxn];//子串
void getnxt()//next数组
{
	int i=1;
	int j=0;
	nxt[0]=0;
	while(i<m)
	{
		if(t[j]==t[i])//情况1
		{
			nxt[i++]=++j;
		}
		else if(!j)//情况2 即j==0
		{
			i++;
		}
		else//情况3
		{
			j=nxt[j-1];
		}
	}
} 
int kmp()
{
	int i=0;
	int j=0;
	while(i<n&&j<m)
	{
		if(s[i]==t[j])
		{
			i++;
			j++;
		}
		else if(j==0)
		{
			i++;
		}
		else
		{
			j=nxt[j-1];
		}
	}
	if(j==m) return i-m+1;
	else return -1;
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d %d",&n,&m);
		for(int i=0;i<n;i++) scanf("%d",&s[i]);
		for(int i=0;i<m;i++) scanf("%d",&t[i]);
		getnxt();
		printf("%d\n",kmp());
	}
	return 0;
}

-------------------------

实例1.

nxt数组只与子串有关,储存的其实是最大公共前后缀

初始化

int i=1; int j=0;nxt[0]=0;

  j=0 i=1              
  a b c d a b c a  
  t[0]=a t[1]=b t[2]=c t[3]=d t[4]=a t[5]=b t[6]=c t[7]=a  
  nxt[0]=0 nxt[1] nxt[2] nxt[3] nxt[4] nxt[5] nxt[6] nxt[7]  
                   
  j=0 i=1              
  a b c d a b c a  
  t[0]=a t[1]=b t[2]=c t[3]=d t[4]=a t[5]=b t[6]=c t[7]=a  
  nxt[0]=0 nxt[1]=0 nxt[2] nxt[3] nxt[4] nxt[5] nxt[6] nxt[7]  
                   
  j=0   i=2            
  a b c d a b c a  
  t[0]=a t[1]=b t[2]=c t[3]=d t[4]=a t[5]=b t[6]=c t[7]=a  
  nxt[0]=0 nxt[1]=0 nxt[2]=0 nxt[3] nxt[4] nxt[5] nxt[6] nxt[7]  
                   
  j=0     i=3          
  a b c d a b c a  
  t[0]=a t[1]=b t[2]=c t[3]=d t[4]=a t[5]=b t[6]=c t[7]=a  
  nxt[0]=0 nxt[1]=0 nxt[2]=0 nxt[3]=0 nxt[4] nxt[5] nxt[6] nxt[7]  
                   
  j=0       i=4        
  a b c d a b c a  
  t[0]=a t[1]=b t[2]=c t[3]=d t[4]=a t[5]=b t[6]=c t[7]=a  
  nxt[0]=0 nxt[1]=0 nxt[2]=0 nxt[3]=0 nxt[4]=j+1=1 nxt[5] nxt[6] nxt[7]  
                   
    j=1       i=5      
  a b c d a b c a  
  t[0]=a t[1]=b t[2]=c t[3]=d t[4]=a t[5]=b t[6]=c t[7]=a  
  nxt[0]=0 nxt[1]=0 nxt[2]=0 nxt[3]=0 nxt[4]=1 nxt[5]=j
+1=2
nxt[6] nxt[7]  
                   
      j=2       i=6    
  a b c d a b c a  
  t[0]=a t[1]=b t[2]=c t[3]=d t[4]=a t[5]=b t[6]=c t[7]=a  
  nxt[0]=0 nxt[1]=0 nxt[2]=0 nxt[3]=0 nxt[4]=1 nxt[5]=2 nxt[6]=j+1=3 nxt[7]  
                   
        j=3       i=7  
  a b c d a b c a  
  t[0]=a t[1]=b t[2]=c t[3]=d t[4]=a t[5]=b t[6]=c t[7]=a  
  nxt[0]=0 nxt[1]=0 nxt[2]=0 nxt[3]=0 nxt[4]=1 nxt[5]=2 nxt[6]=3 nxt[7]  
                   
  j=0             i=7  
  a b c d a b c a  
  t[0]=a t[1]=b t[2]=c t[3]=d t[4]=a t[5]=b t[6]=c t[7]=a  
  nxt[0]=0 nxt[1]=0 nxt[2]=0 nxt[3]=0 nxt[4]=1 nxt[5]=2 nxt[6]=3 nxt[7]=j+1=1  
                   

---------------------- 

实例2

  j=0 i=1              
  a a b a a b a a a
  t[0]=a t[1]=a t[2]=b t[3]=a t[4]=a t[5]=b t[6]=a t[7]=a t[8]=a
  nxt[0]=0 nxt[1] nxt[2] nxt[3] nxt[4] nxt[5] nxt[6] nxt[7] nxt[8]
                   
  j=0 i=1              
  a a b a a b a a a
  t[0]=a t[1]=a t[2]=b t[3]=a t[4]=a t[5]=b t[6]=a t[7]=a t[8]=a
  nxt[0]=0 nxt[1]=j+1=1 nxt[2] nxt[3] nxt[4] nxt[5] nxt[6] nxt[7] nxt[8]
                   
    j=1 i=2            
  a a b a a b a a a
  t[0]=a t[1]=a t[2]=b t[3]=a t[4]=a t[5]=b t[6]=a t[7]=a t[8]=a
  nxt[0]=0 nxt[1]=1 nxt[2] nxt[3] nxt[4] nxt[5] nxt[6] nxt[7] nxt[8]
                   
  j=0   i=2            
  a a b a a b a a a
  t[0]=a t[1]=a t[2]=b t[3]=a t[4]=a t[5]=b t[6]=a t[7]=a t[8]=a
  nxt[0]=0 nxt[1]=1 nxt[2]=0 nxt[3] nxt[4] nxt[5] nxt[6] nxt[7] nxt[8]
                   
  j=0     i=3          
  a a b a a b a a a
  t[0]=a t[1]=a t[2]=b t[3]=a t[4]=a t[5]=b t[6]=a t[7]=a t[8]=a
  nxt[0]=0 nxt[1]=1 nxt[2]=0 nxt[3]=1 nxt[4] nxt[5] nxt[6] nxt[7] nxt[8]
                   
    j=1     i=4        
  a a b a a b a a a
  t[0]=a t[1]=a t[2]=b t[3]=a t[4]=a t[5]=b t[6]=a t[7]=a t[8]=a
  nxt[0]=0 nxt[1]=1 nxt[2]=0 nxt[3]=1 nxt[4]=2 nxt[5] nxt[6] nxt[7] nxt[8]
                   
      j=2     i=5      
  a a b a a b a a a
  t[0]=a t[1]=a t[2]=b t[3]=a t[4]=a t[5]=b t[6]=a t[7]=a t[8]=a
  nxt[0]=0 nxt[1]=1 nxt[2]=0 nxt[3]=1 nxt[4]=2 nxt[5]=3 nxt[6] nxt[7] nxt[8]
                   
        j=3     i=6    
  a a b a a b a a a
  t[0]=a t[1]=a t[2]=b t[3]=a t[4]=a t[5]=b t[6]=a t[7]=a t[8]=a
  nxt[0]=0 nxt[1]=1 nxt[2]=0 nxt[3]=1 nxt[4]=2 nxt[5]=3 nxt[6]=4 nxt[7] nxt[8]
                   
          j=4     i=7  
  a a b a a b a a a
  t[0]=a t[1]=a t[2]=b t[3]=a t[4]=a t[5]=b t[6]=a t[7]=a t[8]=a
  nxt[0]=0 nxt[1]=1 nxt[2]=0 nxt[3]=1 nxt[4]=2 nxt[5]=3 nxt[6]=4 nxt[7]=5 nxt[8]
                   
            j=5     i=8
  a a b a a b a a a
  t[0]=a t[1]=a t[2]=b t[3]=a t[4]=a t[5]=b t[6]=a t[7]=a t[8]=a
  nxt[0]=0 nxt[1]=1 nxt[2]=0 nxt[3]=1 nxt[4]=2 nxt[5]=3 nxt[6]=4 nxt[7]=5 nxt[8]
                   
      j=2           i=8
  a a b a a b a a a
  t[0]=a t[1]=a t[2]=b t[3]=a t[4]=a t[5]=b t[6]=a t[7]=a t[8]=a
  nxt[0]=0 nxt[1]=1 nxt[2]=0 nxt[3]=1 nxt[4]=2 nxt[5]=3 nxt[6]=4 nxt[7]=5 nxt[8]
                   
    j=1             i=8
  a a b a a b a a a
  t[0]=a t[1]=a t[2]=b t[3]=a t[4]=a t[5]=b t[6]=a t[7]=a t[8]=a
  nxt[0]=0 nxt[1]=1 nxt[2]=0 nxt[3]=1 nxt[4]=2 nxt[5]=3 nxt[6]=4 nxt[7]=5 nxt[8]=2
                   

-----------

实例3.

a b x a b c a b c a b y  
a b c a b y              
a b x a b c a b c a b y  
    a b c a b y          
a b x a b c a b c a b y  
      a b c a b y        
a b x a b c a b c a b y  
            省略 c a b y

--------------------------

实例3的符合代码的写法

母串 a b x a b c a b c a b y  
 

i=0

                       
 

j=0

                       
子串 a b c a b y              
nxt[i]= 0 0 0 1 2 0 提前处理好nxt数组
                           

由上表知 s[i]==t[j]=a;是情况一

所以i++; j++;执行后如下表

母串 a b x a b c a b c a b y  
   

i=1

                     
   

j=1

                     
子串 a b c a b y              
  0 0 0 1 2 0 提前处理好nxt数组
                           

由上表知s[i]==t[j]=b;是情况一

所以i++; j++;执行后如下表

母串 a b x a b c a b c a b y  
     

i=2

                   
     

j=2

                   
子串 a b c a b y              
  0 0 0 1 2 0 提前处理好nxt数组
                           

由上表知s[i]!=t[j]且j!=0;情况三 

所以j=nxt[j-1]=nxt[1]=0;执行后如下表

母串 a b x a b c a b c a b y  
     

i=2

                   
 

j=0

                       
子串 a b c a b y              
  0 0 0 1 2 0 提前处理好nxt数组
                           

由上表知j==0;是情况二;

所以i++;执行后如下表

母串 a b x a b c a b c a b y  
       

i=3

                 
 

j=0

                       
子串 a b c a b y              
  0 0 0 1 2 0 提前处理好nxt数组
                           

接下来好几步都是 s[i]==t[j],是情况一 ;

所以i++; j++;执行后如下表

母串 a b x a b c a b c a b y  
         

i=4

i=5

i=6

i=7

         
   

j=1

j=2

j=3

j=4

               
子串 a b c a b y              
  0 0 0 1 2 0 提前处理好nxt数组
                           

直到不匹配出现

母串 a b x a b c a b c a b y  
                 

i=8

       
           

j=5

             
子串 a b c a b y              
  0 0 0 1 2 0 提前处理好nxt数组
                           

由上表知s[i]!=t[j]且j!=0;情况三 

所以j=nxt[j-1]=nxt[4]=2;执行后如下表

母串 a b x a b c a b c a b y  
                 

i=8

       
     

j=2

                   
子串 a b c a b y              
  0 0 0 1 2 0 提前处理好nxt数组
                           

由上表知s[i]==t[j];是情况一

所以i++; j++;执行后如下表

母串 a b x a b c a b c a b y  
                   

i=9

     
       

j=3

                 
子串 a b c a b y              
  0 0 0 1 2 0 提前处理好nxt数组
                           

由上表知s[i]==t[j],是情况一 ;

所以i++; j++;执行后如下表

母串 a b x a b c a b c a b y  
                     

i=10

   
         

j=4

               
子串 a b c a b y              
  0 0 0 1 2 0 提前处理好nxt数组
                           

由上表知s[i]==t[j],是情况一 ;

所以i++; j++;执行后如下表

母串 a b x a b c a b c a b y  
                       

i=11

 
           

j=5

             
子串 a b c a b y              
  0 0 0 1 2 0 提前处理好nxt数组
                           

-----------------------

实例4

a b c x a b c d a b x a b c d a b c d a b c y                    
a b c d a b c y                                                  
a b c x a b c d a b x a b c d a b c d a b c y                    
      a b c d a b c y                                            
a b c x a b c d a b x a b c d a b c d a b c y                    
        a b c d a b c y                                          
a b c x a b c d a b x a b c d a b c d a b c y                    
                省略 c d a b c y                                  
a b c x a b c d a b x a b c d a b c d a b c y                    
                    a b c d a b c y                              
a b c x a b c d a b x a b c d a b c d a b c y                    
                      a b c d a b c y                            
a b c x a b c d a b x a b c d a b c d a b c y                    
                                    d a b c y                    

猜你喜欢

转载自blog.csdn.net/tingtingyuan/article/details/81811167