基础板子
下标从1开始
for(int i=2,j=0;i<=n;i++)
{
while(j&&s1[i]!=s1[j+1])j=ne[j];
if(s1[i]==s1[j+1])j++;
ne[i]=j;
}
for(int i=1,j=0;i<=m;i++)
{
while(j&&s2[i]!=s1[j+1])j=ne[j];
if(s2[i]!=s1[j+1])j++;
if(j==n)
{
j=ne[j];
}
}
下标从0开始(使用string)
for(int i=1,j=0;i<n;i++)
{
while(j&&s1[i]!=s1[j])j=ne[j-1];
if(s1[i]==s1[j])j++;
ne[i]=j;
}
for(int i=0,j=0;i<m;i++)
{
while(j&&s2[i]!=s1[j])j=ne[j-1];
if(s2[i]==s1[j])j++;
if(j==n)
{
j=ne[j-1];
}
}
next数组层面的操作
求最小循环节长度
len-ne[len];
残缺循环节长度
len%(len-ne[len]);
补全循环节个数
(len-ne[len])-len%(len-ne[len]);
找出每个循环节的结束
while(!ne[len])
{
st.push(ne[len]);
len=ne[len];
}
while(!st.empty())
{
printf("%d",st.top());
}
kmp层面进行操作
求可以被分割成多少相同的字符串
for(int i=1,j=0;i<m;i++)
{
while(j&&s1[j+1]!=s2[i])j=ne[j];
if(s1[j+1]==s2[i])j++;
if(j==n)
{
j=0;//关键
cnt++;
}
}
求存在多少重复的字符串
for(int i=1,j=0;i<m;i++)
{
while(j&&s1[j+1]!=s2[i])j=ne[j];
if(s1[j+1]==s2[i])j++;
if(j==n)
{
j=ne[j];//关键
cnt++;
}
}