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=0i=1       
 abcdabca 
 t[0]=at[1]=bt[2]=ct[3]=dt[4]=at[5]=bt[6]=ct[7]=a 
 nxt[0]=0nxt[1]nxt[2]nxt[3]nxt[4]nxt[5]nxt[6]nxt[7] 
          

 

 j=0i=1       
 abcdabca 
 t[0]=at[1]=bt[2]=ct[3]=dt[4]=at[5]=bt[6]=ct[7]=a 
 nxt[0]=0nxt[1]=0nxt[2]nxt[3]nxt[4]nxt[5]nxt[6]nxt[7] 
          

 

 j=0 i=2      
 abcdabca 
 t[0]=at[1]=bt[2]=ct[3]=dt[4]=at[5]=bt[6]=ct[7]=a 
 nxt[0]=0nxt[1]=0nxt[2]=0nxt[3]nxt[4]nxt[5]nxt[6]nxt[7] 
          

 

 j=0  i=3     
 abcdabca 
 t[0]=at[1]=bt[2]=ct[3]=dt[4]=at[5]=bt[6]=ct[7]=a 
 nxt[0]=0nxt[1]=0nxt[2]=0nxt[3]=0nxt[4]nxt[5]nxt[6]nxt[7] 
          

 

 j=0   i=4    
 abcdabca 
 t[0]=at[1]=bt[2]=ct[3]=dt[4]=at[5]=bt[6]=ct[7]=a 
 nxt[0]=0nxt[1]=0nxt[2]=0nxt[3]=0nxt[4]=j+1=1nxt[5]nxt[6]nxt[7] 
          

 

  j=1   i=5   
 abcdabca 
 t[0]=at[1]=bt[2]=ct[3]=dt[4]=at[5]=bt[6]=ct[7]=a 
 nxt[0]=0nxt[1]=0nxt[2]=0nxt[3]=0nxt[4]=1nxt[5]=j
+1=2
nxt[6]nxt[7] 
          

 

   j=2   i=6  
 abcdabca 
 t[0]=at[1]=bt[2]=ct[3]=dt[4]=at[5]=bt[6]=ct[7]=a 
 nxt[0]=0nxt[1]=0nxt[2]=0nxt[3]=0nxt[4]=1nxt[5]=2nxt[6]=j+1=3nxt[7] 
          

 

    j=3   i=7 
 abcdabca 
 t[0]=at[1]=bt[2]=ct[3]=dt[4]=at[5]=bt[6]=ct[7]=a 
 nxt[0]=0nxt[1]=0nxt[2]=0nxt[3]=0nxt[4]=1nxt[5]=2nxt[6]=3nxt[7] 
          

 

 

 j=0      i=7 
 abcdabca 
 t[0]=at[1]=bt[2]=ct[3]=dt[4]=at[5]=bt[6]=ct[7]=a 
 nxt[0]=0nxt[1]=0nxt[2]=0nxt[3]=0nxt[4]=1nxt[5]=2nxt[6]=3nxt[7]=j+1=1 
          

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

实例2

 j=0i=1       
 aabaabaaa
 t[0]=at[1]=at[2]=bt[3]=at[4]=at[5]=bt[6]=at[7]=at[8]=a
 nxt[0]=0nxt[1]nxt[2]nxt[3]nxt[4]nxt[5]nxt[6]nxt[7]nxt[8]
          

 

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

 

  j=1i=2      
 aabaabaaa
 t[0]=at[1]=at[2]=bt[3]=at[4]=at[5]=bt[6]=at[7]=at[8]=a
 nxt[0]=0nxt[1]=1nxt[2]nxt[3]nxt[4]nxt[5]nxt[6]nxt[7]nxt[8]
          

 

 j=0 i=2      
 aabaabaaa
 t[0]=at[1]=at[2]=bt[3]=at[4]=at[5]=bt[6]=at[7]=at[8]=a
 nxt[0]=0nxt[1]=1nxt[2]=0nxt[3]nxt[4]nxt[5]nxt[6]nxt[7]nxt[8]
          

 

 j=0  i=3     
 aabaabaaa
 t[0]=at[1]=at[2]=bt[3]=at[4]=at[5]=bt[6]=at[7]=at[8]=a
 nxt[0]=0nxt[1]=1nxt[2]=0nxt[3]=1nxt[4]nxt[5]nxt[6]nxt[7]nxt[8]
          

 

  j=1  i=4    
 aabaabaaa
 t[0]=at[1]=at[2]=bt[3]=at[4]=at[5]=bt[6]=at[7]=at[8]=a
 nxt[0]=0nxt[1]=1nxt[2]=0nxt[3]=1nxt[4]=2nxt[5]nxt[6]nxt[7]nxt[8]
          

 

   j=2  i=5   
 aabaabaaa
 t[0]=at[1]=at[2]=bt[3]=at[4]=at[5]=bt[6]=at[7]=at[8]=a
 nxt[0]=0nxt[1]=1nxt[2]=0nxt[3]=1nxt[4]=2nxt[5]=3nxt[6]nxt[7]nxt[8]
          

 

    j=3  i=6  
 aabaabaaa
 t[0]=at[1]=at[2]=bt[3]=at[4]=at[5]=bt[6]=at[7]=at[8]=a
 nxt[0]=0nxt[1]=1nxt[2]=0nxt[3]=1nxt[4]=2nxt[5]=3nxt[6]=4nxt[7]nxt[8]
          

 

     j=4  i=7 
 aabaabaaa
 t[0]=at[1]=at[2]=bt[3]=at[4]=at[5]=bt[6]=at[7]=at[8]=a
 nxt[0]=0nxt[1]=1nxt[2]=0nxt[3]=1nxt[4]=2nxt[5]=3nxt[6]=4nxt[7]=5nxt[8]
          

 

      j=5  i=8
 aabaabaaa
 t[0]=at[1]=at[2]=bt[3]=at[4]=at[5]=bt[6]=at[7]=at[8]=a
 nxt[0]=0nxt[1]=1nxt[2]=0nxt[3]=1nxt[4]=2nxt[5]=3nxt[6]=4nxt[7]=5nxt[8]
          

 

   j=2     i=8
 aabaabaaa
 t[0]=at[1]=at[2]=bt[3]=at[4]=at[5]=bt[6]=at[7]=at[8]=a
 nxt[0]=0nxt[1]=1nxt[2]=0nxt[3]=1nxt[4]=2nxt[5]=3nxt[6]=4nxt[7]=5nxt[8]
          

 

  j=1      i=8
 aabaabaaa
 t[0]=at[1]=at[2]=bt[3]=at[4]=at[5]=bt[6]=at[7]=at[8]=a
 nxt[0]=0nxt[1]=1nxt[2]=0nxt[3]=1nxt[4]=2nxt[5]=3nxt[6]=4nxt[7]=5nxt[8]=2
          

 

-----------

实例3.

abxabcabcaby 
abcaby       

 

abxabcabcaby 
  abcaby     

 

abxabcabcaby 
   abcaby    

 

abxabcabcaby 
      省略caby

 

 

 

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

实例3的符合代码的写法

母串abxabcabcaby 
 

i=0

            
 

j=0

            
子串abcaby       
nxt[i]=000120提前处理好nxt数组
              

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

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

母串abxabcabcaby 
  

i=1

           
  

j=1

           
子串abcaby       
 000120提前处理好nxt数组
              

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

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

母串abxabcabcaby 
   

i=2

          
   

j=2

          
子串abcaby       
 000120提前处理好nxt数组
              

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

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

母串abxabcabcaby 
   

i=2

          
 

j=0

            
子串abcaby       
 000120提前处理好nxt数组
              

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

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

母串abxabcabcaby 
    

i=3

         
 

j=0

            
子串abcaby       
 000120提前处理好nxt数组
              

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

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

母串abxabcabcaby 
     

i=4

i=5

i=6

i=7

     
  

j=1

j=2

j=3

j=4

        
子串abcaby       
 000120提前处理好nxt数组
              

直到不匹配出现

母串abxabcabcaby 
         

i=8

    
      

j=5

       
子串abcaby       
 000120提前处理好nxt数组
              

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

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

母串abxabcabcaby 
         

i=8

    
   

j=2

          
子串abcaby       
 000120提前处理好nxt数组
              

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

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

母串abxabcabcaby 
          

i=9

   
    

j=3

         
子串abcaby       
 000120提前处理好nxt数组
              

 

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

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

母串abxabcabcaby 
           

i=10

  
     

j=4

        
子串abcaby       
 000120提前处理好nxt数组
              

 

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

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

母串abxabcabcaby 
            

i=11

 
      

j=5

       
子串abcaby       
 000120提前处理好nxt数组
              

 

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

实例4

abcxabcdabxabcdabcdabcy          
abcdabcy                         

 

abcxabcdabxabcdabcdabcy          
   abcdabcy                      
abcxabcdabxabcdabcdabcy          
    abcdabcy                     
abcxabcdabxabcdabcdabcy          
        省略cdabcy                 
abcxabcdabxabcdabcdabcy          
          abcdabcy               
abcxabcdabxabcdabcdabcy          
           abcdabcy              
abcxabcdabxabcdabcdabcy          
                  dabcy          

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值