洛谷P3375 【模板】KMP字符串匹配

1.题目描述

题目来源:洛谷P3375 【模板】KMP字符串匹配
洛谷P3375 【模板】KMP字符串匹配_第1张图片

洛谷P3375 【模板】KMP字符串匹配_第2张图片

2.AC代码

2.1AC代码1

#include
#include
#define MAXN 1000010
using namespace std;
int kmp[MAXN];
int la,lb,j; 
char a[MAXN],b[MAXN];
int main()
{
    cin>>a+1;//从下标1开始输入
    cin>>b+1;
    la=strlen(a+1);
    lb=strlen(b+1);
    for (int i=2;i<=lb;i++)//求子串的各个位置最大最大公共前后缀
	{     
	   while(j>0&&b[i]!=b[j+1])
        j=kmp[j];    
       if(b[j+1]==b[i])
       j++;    
       kmp[i]=j;
    }
    j=0;
    for(int i=1;i<=la;i++)
	   {
          while(j>0&&b[j+1]!=a[i])
           j=kmp[j];
          if (b[j+1]==a[i]) 
           j++;
          if (j==lb) {cout<<i-lb+1<<endl;j=kmp[j];}
       }
    for (int i=1;i<=lb;i++)
    cout<<kmp[i]<<" ";
    return 0;
}

AC代码2:

#include
#include
#define max 1000001
char str[max];
char arr[max]; 
int next[max];
int nextval[max];
void getnext(char arr[],int next[])
{
	int i=1;
	next[0]=0;
	next[1]=0;
	int j=0;
	while(i<strlen(arr+1))
	{
		if(j==0||arr[i]==arr[j])
		{
			i++;
			j++;
			next[i]=j;
			
		}
		else
		j=next[j];
  }	
}
void kmp(char arr[],char str[],int next[])
{
           int i=1;
           int j=1;
           while(i<=strlen(str+1))
        {
        	if(j==0||arr[j]==str[i])
        	{
        		i++;
        		j++;
			}
           	else
           	j=next[j];
           	if(j>strlen(arr+1)-1)
           	{
           		printf("%d\n", i-strlen(arr+1)+1);
           		j=1;
           		i=i-strlen(arr+1)+2;
			}
		}
} 
void getnextval(char arr[],int nextval[])
{
	int i=1;
	next[0]=0;
	next[1]=0;
	int j=0;
	while(i<strlen(arr+1))
	{
		if(j==0||arr[i]==arr[j])
		{
			i++;
			j++;
			if(arr[i]!=arr[j])
			nextval[i]=j;
			else
			nextval[i]=nextval[j]; 		
		}
		else
		j=nextval[j];
	
}
}
int main()
{

    scanf("%s",str+1);
	scanf("%s",arr+1);
    arr[strlen(arr+1)+1]='1';
	getnextval(arr,nextval);
	kmp(arr,str,nextval);
	getnext(arr,next);
	for(int i=2;i<=strlen(arr+1);i++)
	{
		printf("%d ",next[i]-1);
	}
}

你可能感兴趣的:(算法错题总结)