欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

KMP算法

程序员文章站 2022-05-02 17:44:13
...

发布文章 博文管理我的博客退出 Trash Temp KMP算法 KMP算法 KMP算法 KMP算法 KMP算法 KMP算法 ## 浅谈KMP算法

① 寻找next(有的地方是F数组)数组

例如:T(长串) P(短串)

Index:   0    1    2    3    4    5    6    7    8    9
    T:   A    B    A    B    A    B    A    B    C    A          ( 1 )
    P:   0    0    1    2    3    4    5    6    0    1          ( 2 )
 next:  -1    0    0    1    2    3    4    5    6    0    1

( 1 ) . 寻找前缀后缀最长公共长度;
( 2 ) . 求next数组;

next数组考虑的是除当前字符外的最长相同牵住后缀,所以通过 ( 1 ) 求得各个前缀后缀的公共元素的最大长度后,只要稍作变形即可:
将第一步中求得的值整体后移一位,然后初值赋为-1;

②求next数组代码

void Getnext()
  {
    int i=0;
    int j=-1;
    int p=strlen(P);
    next[0]=-1;
    while (i<p)
    {
        if (j==-1 || P[i]==P[j])
        {
            i++;
            j++;
            next[i]=j;
        }
        else
        {
            j=next[j];
        }
    }
}

例题:已知字符串T,P,求P在T中出现的次数(可以重叠)
input :ZYZYZYZ
output:3

代码实现:

 #include<stdio.h> 
 #include<string.h> 
 using namespace std;
 const int N=1e6+5;
 char T[N],P[N];
 int next[N];
 int cnt;void find();
 void Getnext();
 int main()
 {
     scanf("%s %s",T,P);
     find();
     printf("%d\n",cnt);
     return 0;
 }
 void find()
 {
     Getnext();
     int n=strlen(T);
     int m=strlen(P);
     int j=0;
     for(int i=0; i<n; i++)
     {
         while (j && T[i]!=P[j])
         {
             j=next[j];
         }
         if(T[i]==P[j])
         {
             j++;
         }
         if(j==m)
         {
             cnt++;
         }
     }
 }
 void Getnext()
 {
     int i=0;
     int j=-1;
     int p=strlen(P);
     next[0]=-1;
     while (i<p)
     {
         if (j==-1 || P[i]==P[j])
         {
             i++;
             j++;
             next[i]=j;
         }
         else
         {
             j=next[j];
         }
     }
 }

例题链接

若上个例题改为不可重复,则代码实现为:

#include<string.h> 
using namespace std;
const int N=1e6+5;
char T[N],P[N];
int next[N];
int cnt;void find();
void Getnext();
int main()
{
    scanf("%s %s",T,P);                      
    find();                                 
    printf("%d\n",cnt);              
    return 0;
}
void find()
{
    Getnext();
    int n=strlen(T);
    int m=strlen(P);
    int j=0;
    for(int i=0; i<n; i++)
    {
        if(j && T[i]!=P[j])
        {
            j=next[j];
        }
        if(T[i]==P[j])
        {
            j++;
        }
        if(j==m)
        {
            cnt++;
            j=0;
        }
    }
}void Getnext()
{
    int i=0;
    int j=-1;
    int p=strlen(P);
    next[0]=-1;
    while (i<p)
    {
        if (j==-1 || P[i]==P[j])
        {
            i++;
            j++;
            next[i]=j;
        }
        else
        {
            j=next[j];
        }
    }
}

相关题目:

  1. G -Power Strings
    2.D - Prefixes and Suffixes

这是本人第一次写博客,如有不对请多包涵,如果对您有所帮助请继续支持。

相关标签: KMP算法