码迷,mamicode.com
首页 > 其他好文 > 详细

扩展KMP

时间:2017-08-22 01:48:58      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:否则   简单   std   c++   end   .com   next数组   log   ges   

有两个S,T串,扩展KMP求,每一个S串的后缀和T串的最长公共前缀长度。

详细介绍:https://wenku.baidu.com/view/8e9ebefb0242a8956bece4b3.html

 

简单介绍一下:

扩展KMP,通过先处理T串next数组,然后用同样的方法去处理S,T;

具体意义:

next[i] : T的后缀 i ,和T串本身的最长公共前缀长度。

extend[i] : S的后缀 i ,和T串的最长公共前缀长度。

技术分享

L : 能保证匹配的最长长度,然后L很短,extend[k+1] = L;

否则:从p后面开始匹配,更新。这样匹配extend就算完了。

那么,前面用的next 数组怎么得来呢? 可以发现next和extend 定义极为类似,这样同样的思路,T自己匹配自己。

#include <bits/stdc++.h>

using namespace std;

const int MAX_N  = 101010;

int next[MAX_N],extend[MAX_N];

void getnext(char *T) {
    int a = 0;
    int Tlen = strlen(T);
    next[0] = Tlen;

    while(a<Tlen-1&&T[a]==T[a+1]) a++;
    next[1] = a;

    a = 1;

    for(int k=2; k < Tlen; k++) {
        int p = a + next[a] - 1,L = next[k-a];
        if((k-1)+L>=p) {
            int j = (p-k+1) > 0 ? p - k + 1 : 0;
            while(k+j<Tlen&&T[k+j]==T[j])
                j++;
            next[k] = j;
            a = k;
        }
        else next[k] = L;
    }

}

void getextend(char *S,char *T) {
    int a = 0;
    getnext(T);

    int Slen = strlen(S);
    int Tlen = strlen(T);

    int MinLen = Slen < Tlen ? Slen : Tlen;
    while(a<MinLen&&S[a]==T[a]) a++;
    extend[0] = a;
    a = 0;

    for(int k=1; k < Slen; k++) {
        int p = a + extend[a] - 1,L = next[k-a];
        if((k-1)+L>=p) {
            int j = (p - k + 1) > 0 ? p - k + 1:0;
            while(k+j<Slen&&j<Tlen&&S[k+j]==T[j]) j++;
            extend[k] = j;
            a = k;
        }
        else extend[k] = L;
    }

}

 

扩展KMP

标签:否则   简单   std   c++   end   .com   next数组   log   ges   

原文地址:http://www.cnblogs.com/TreeDream/p/7407420.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!