[模板]kmp算法

很详细的参考资料:
July大神的从头到尾彻底理解KMP

有三个对应关系:

  • Next 数组存的是 到当前 j 位置前的 的最长相同前缀后缀长度。
  • 与此类似的是 最长长度表,是 到当前 j 的位置 的最长相同前缀后缀长度。两者存在平移一个单位关系。
  • 模式串的移动。失配时,模式串向右移动的位数为:已匹配字符数 - 失配字符的上一位字符所对应的最大长度值

具体实现:

//s 为母串, t 为模式串
int Next[MAXN];
void getNext(char *t){
    int len=strlen(t);
    int k=-1,j=0;//k 为之前的位置,j为当前位置
    Next[0]=-1;
    //递归的思想求 Next[]
    while(j<len-1){
        if(k==-1||t[k]==t[j]){
            Next[++j]=++k;
        }
        else k=Next[k];
    }
}
int kmp(char *s,char *t){
    int i=0,j=0,lens=strlen(s),lent=strlen(t);
    while(j<lent && i<lens){
        if(j==-1||s[i]==t[j]) i++,j++;
        else j=Next[j];
    }
    if(j==lent) return i-j;
    else return -1;
}

优化Next数组, getNext() 后具体实现:

int Next[MAXN];
void getNext(char *t){
    int len=strlen(t);
    int k=-1,j=0;
    Next[0]=-1;
    while(j<len-1){
        if(k==-1||t[k]==t[j]){
            j++;
            k++;
            if(t[k]!=t[j]) Next[j]=k;
            else Next[j]=Next[k];
        }
        else k=Next[k];
    }
}
int kmp(char *s,char *t){//返回第一个位置
    int i=0,j=0,lens=strlen(s),lent=strlen(t);
    while(j<lent && i<lens){
        if(j==-1||s[i]==t[j]) i++,j++;
        else j=Next[j];
    }
    if(j==lent) return i-j;
    else return -1;
}

另外注意 const char * strstr ( const char * str1, const char * str2 );
返回一个指针位置。在c++11优化下有时候还比 kmp 快。(?总之优化后速度是不慢的
用法:

int pos=strstr(s,t)-s;

Ps.刚好数据结构上到kmp要求整理成word,博客上也没有kmp的东西,就整理一下发出来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值