1.KMP算法

这个博客写的不错:http://www.cnblogs.com/SYCstudio/p/7194315.html

模板:

next数组的求解,那个循环本质就是如果相同前后缀不能加上该位置成就该位置的next数组就一直找相同前后缀的相同前后缀。

求解前缀数组F(也叫next数组):

for (int i=1;i<m;i++)
{
    int j=F[i-1];
    while ((B[j+1]!=B[i])&&(j>=0))
        j=F[j];
    if (B[j+1]==B[i])
        F[i]=j+1;
    else
        F[i]=-1;
}

利用F数组寻找匹配,这里我们是每找到一个匹配就输出其开始的位置:

while (i<n)
{
    if (A[i]==B[j])
    {
        i++;
        j++;
        if (j==m)
        {
            printf("%d\n",i-m+1);
            j=F[j-1]+1;
        }
    }
    else
    {
        if (j==0)
            i++;
        else
            j=F[j-1]+1;
    }
}

例题1:P3375 【模板】KMP字符串匹配

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define mem(a,b) memset((a),(b),sizeof(a))
const int N=1e3+5;
int f[N]={-1};
char a[N*N];
char b[N];

int main()
{
    /*ios::sync_with_stdio(false);
    cin.tie(0);*/
    scanf("%s",a);
    scanf("%s",b);
    int m=strlen(b);
    int n=strlen(a);
    for(int i=1;i<m;i++)
    {
        int j=f[i-1];
        while(b[j+1]!=b[i]&&j>=0)j=f[j];
        if(b[j+1]==b[i])f[i]=j+1;
        else f[i]=-1;
    }
    
    int i=0,j=0;
    while(i<n)
    {
        if(a[i]==b[j])
        {
            i++;
            j++;
            if(j==m)
            {
                printf("%d\n",i-m+1); 
                j=f[j-1]+1;
            }
        }
        else 
        {
            if(j==0)i++;
            else j=f[j-1]+1;
        }
    }
    
    for(int i=0;i<m;i++)
    {
        printf("%d",f[i]+1);
        if(i!=m-1)printf(" ");
        else printf("\n");
    }
    return 0;
} 
View Code

相关文章:

  • 2021-02-13
  • 2021-07-26
  • 2022-12-23
  • 2021-10-07
  • 2021-07-02
  • 2021-04-15
猜你喜欢
  • 2021-10-14
  • 2021-08-31
  • 2021-05-31
  • 2021-08-29
  • 2022-01-15
相关资源
相似解决方案