【代码】
#include<iostream>
#include<cstdio>
#include<cstring>
#define fo(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
char p[100000],s[100000];
int f[100000],a[100000],ans[100000];
void getfail()
{
int j=0;
int len=strlen(s+1);
fo(i,2,len)
{
while(j && s[j+1]!=s[i]) j=f[j];
if(s[j+1]==s[i]) j++;
f[i]=j;
}
}
void find()
{
int j=0;
int len=strlen(p+1),ls=strlen(s+1);
fo(i,1,len)
{
while(j && s[j+1]!=p[i]) j=f[j];
if(s[j+1]==p[i]) j++;
if(j==ls) ans[++ans[0]]=i-ls+1;
}
}
int main()
{
scanf("%s%s",p+1,s+1);
getfail();
find();
fo(i,1,ans[0]) printf("%d\n",ans[i]);
return 0;
}
https://www.cnblogs.com/zhangtianq/p/5839909.html
对于KMP的理解感觉这篇博客写的是最详细的。
KMP算法简介:
KMP算法是一种高效的字符串匹配算法,关于字符串匹配最简单的就是BF算法。BF算法是用两个游标分别指向母串S,模式串T,从开头向后面依次比较字符是否相等,如果相等继续同时向后滑动两个游标,不相等的话,T的游标回溯至开头,S的游标回溯至起初游标的下一位,这种算法原理非常简单,小学生都可以想的到。
KMP算法是在BF算法的基础上加以改进的,它的特点是在遇到字符不匹配时候维持母串T的游标不动,而把模式串向右移动,具体移动到哪一个元素下标,这就是算法的核心思想之处了。
假如母串的i处和模式串的j处不匹配,那么就令k=next(j),表示的意思就是:模式串在j处出现不匹配现象,此时应该将模式串向后一定到下标为k的游标处,在此与之前不匹配的元素进行比较。