有两种设置f数组的方式
一种是 f[i] 代表i之前的字符串的最长相同前缀后缀长度,f[0]初始化为-1
一种是 f[i] 代表1~i+1的字符串的最长相同前缀后缀长度,f[0]初始化为0
不错的KMP算法博客:https://blog.csdn.net/f1033774377/article/details/82556438
注意这道题要求输出第二种
初始化为0
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <cstring>
#include <stdio.h>
#include <queue>
#include <algorithm>
#include <vector>
#define MAX 1000010
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
int n,m,k;
char s1[MAX];
char s2[MAX];
int f[MAX];
int main()
{
cin>>s1>>s2;
int len1=strlen(s1);
int len2=strlen(s2);
f[0]=f[1]=0;
for(int i=1;i<len2;i++){
int j=f[i];
while(s2[j]!=s2[i]&&j>0){
j=f[j];
}
if(s2[i]==s2[j])
f[i+1]=j+1;
else
f[i+1]=0;
}
// for(int i=0;i<len2;i++){
// printf("%d",f[i]);
// printf(i==len2-1?"\n":" ");
// }
for(int i=0,j=0;i<len1;){
//printf("%d %d++++%c %c\n",i,j,s1[i],s2[j]);
if(s1[i]==s2[j]){
i++;
j++;
if(j==len2){
printf("%d\n",i-j+1);
j=f[j];
}
}
else {
if(j==0)i++;
else j=f[j];
}
}
for(int i=1;i<=len2;i++){
printf("%d",f[i]);
printf(i==len2?"\n":" ");
}
return 0;
}
初始化为-1
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <cstring>
#include <stdio.h>
#include <queue>
#include <algorithm>
#include <vector>
#define MAX 1000010
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
int n,m,k;
char s1[MAX];
char s2[MAX];
int f[MAX];
int main()
{
cin>>s1>>s2;
int len1=strlen(s1);
int len2=strlen(s2);
f[0]=-1;
for(int i=1;i<len2;i++){
int j=f[i-1];
while(s2[j+1]!=s2[i]&&j>=0){
j=f[j];
}
if(s2[i]==s2[j+1])
f[i]=j+1;
else
f[i]=-1;
}
// for(int i=0;i<len2;i++){
// printf("%d",f[i]);
// printf(i==len2-1?"\n":" ");
// }
for(int i=0,j=0;i<len1;){
//printf("%d %d++++%c %c\n",i,j,s1[i],s2[j]);
if(s1[i]==s2[j]){
i++;
j++;
if(j==len2){
printf("%d\n",i-j+1);
j=f[j-1]+1;
}
}
else {
if(j==0)i++;
else j=f[j-1]+1;
}
}
for(int i=0;i<len2;i++){
printf("%d",f[i]+1);
printf(i==len2-1?"\n":" ");
}
return 0;
}