经典算法之KMP

KMP是处理字符串匹配的常用算法之一,这个理解起来比较简单(其实我感觉还是挺费劲的,但是书上都这么说,我果然还是太菜~),还有别的算法像是后缀数组、AC自动机等等,以后有机会再写一下

基本思想我也是学习的Matrix67的博客 http://www.matrix67.com/blog/archives/115,我就简单把代码整理一下,加了一点我自己的注释

#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
#define maxn 1000
string A;
string B;
int p[maxn];
//自匹配过程,找出满足B[1,p[j]]=B[j-p[j]+1,j]的最大p[j](就是前X个字符==后x个字符的最大x)
void predeal()
{
    int m=B.size();
    p[0]=-1;//初始化p[0],也就是执行到p[0]说明该位置不存在自匹配了
    int j=-1;
    for(int i=1;i<m;i++)
    {
        //如果当前字符不相等,就将j移动到上一个自匹配位置
        while(j>-1&&B[j+1]!=B[i])
        j=p[j];
        //如果相等,自匹配位置+1即可
        if(B[j+1]==B[i])
        j++;
        //对自匹配数组赋值
        p[i]=j;
    }
}
//主要匹配过程
void kmp()
{
    bool flag=false;
    predeal();
    int n=A.size();
    int m=B.size();
    int j=-1;
    for(int i=0;i<n;i++)
    {
        //如果当前位置不相等,将j移动到上一个B串自匹配位置,相当于将B向A的右侧移动,直到再次匹配
        while(j>-1&&A[i]!=B[j+1])
            j=p[j];
        //如果相等,那么将j+1
        if(A[i]==B[j+1])
            j++;
        //如果j==m-1,说明找到啦,over?no!there may be more answers~
        if(j==m-1)
        {
            cout<<"Pattern occurs at "<<i-m+1<<endl;
            flag=true;
            break;//    solve problems that only have to answer yes or no
            //j=p[j];   continue to find more suitable patterns
        }
    }
    if(!flag)
    cout<<"cant find string b in string a"<<endl;
}
int main()
{
    while(cin>>A>>B)
    {
        kmp();
        return 0;
    }
}

 

posted @ 2017-04-05 10:08  淡定的大树懒  阅读(194)  评论(0编辑  收藏  举报