10.13总结------kmp算法

自周四之后这两天,没怎么系统的看,今天周六把作业,等等琐事处理完了,明天一天没有别的事,会系统的看看知识点。

今天把kmp算法看了一看,现在终于明白了:

先理解一下前缀和后缀:

则图中最长公共前缀后缀长度为0;
下面再以”ABCDABD”为例,进行介绍:
- ”A”的前缀和后缀都为空集,共有元素的长度为0;
- ”AB”的前缀为[A],后缀为[B],共有元素的长度为0;
- ”ABC”的前缀为[A, AB],后缀为[BC, C],共有元素的长度0;
- ”ABCD”的前缀为[A, AB, ABC],后缀为[BCD, CD, D],共有元素的长度为0;
- ”ABCDA”的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A],共有元素为”A”,长度为1;
- ”ABCDAB”的前缀为[A, AB, ABC, ABCD, ABCDA],后缀为[BCDAB, CDAB, DAB, AB, B],共有元素为”AB”,长度为2;
- ”ABCDABD”的前缀为[A, AB, ABC, ABCD, ABCDA, ABCDAB],后缀为[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的长度为0。
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
char a[1007],b[1007];
int p[1007],n,m;
void pre()// 预处理相当于b串,从1到b的长度,找前缀等于后缀的最长长度。
{
    p[1]=0;
    int j=0;
    for(int i=1;i<m;i++)
    {
        while(j>0&&b[j+1]!=b[i+1])j=p[j];
        if(b[i+1]==b[j+1])j++;
        p[i+1]=j;
    }
}
    /*int kmp()
    {
        int ans=0;
        int j=0;
        for(int i=0;i<n;i++)
        {
           while(j>0&&b[j+1]!=a[i+1])j=p[j];
        if(b[j+1]==a[i+1])j++;
       if(j==m)
       {
           ans++;
           j=0;
       }
        }
        return ans;
    }*/
    void kmp()
    {
        int j=0;
        for(int i=0;i<n;i++)
        {
            while(j>0&&b[j+1]!=a[i+1])j=p[j];
            if(b[j+1]==a[i+1])j++;
            if(j==m)
            {
                cout<<i+1-m+1<<endl;
                j=p[j];
            }
        }
    }
int main()
{
    while(cin>>a+1)
    {
        if(a[1]=='#')break;
        cin>>b+1;
        m=strlen(b+1);
        n=strlen(a+1);
        pre();
        //cout<<kmp()<<endl;
        kmp();
    }
}

 

具体请看大佬写的:

https://blog.csdn.net/starstar1992/article/details/54913261/

如果你看不懂KMP算法,一定要看看这个视频!!!!!!!!!!!虽然讲的慢,但是很详细!!!!

上:http://v.youku.com/v_show/id_XODYxNjExODQ=.html     第 34分钟开始 

下:http://www.56.com/u28/v_NjAwMzA0ODA.html     
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值