当前位置: 主页 > JAVA语言

java kmp 字符串匹配-:快速查找匹配串的算法问题解决:j数组

发布时间:2023-06-09 10:01   浏览次数:次   作者:佚名

KMP(快速查找匹配串的算法)

问题解决:判断B是否A的子串,并找到字符串B中在字符串A中的位置。

时间复杂度 :O(N+M), N,M分别是字符串A和B的长度。

核心点:对于字符串B,数组next[i]表示B中以i结尾的非前缀子串与B的前缀能够匹配的最长长度。也就是前缀B[1]...B[next[i]]和B[i-next[i]+1]....B[i]相等,很明显B[i]==B[next[i]],有了next数组之后,我们就可以对A,B字符串进行匹配了。

匹配流程:

设i,j分别是指向A和B的下标,此时A[i-j]...A[i-1] == B[1]...B[j]java kmp 字符串匹配,也就是说B的前j的字符已经匹配成功了。如果A[i]==B[j+1],i++,j++。如果A[i]!=B[j+1],j=next[j],直到j==0或者A[i]==B[j+1], 为什么这样做?那是因为B[1]...B[next[j]] == B[j-next[j]+1]...B[j],所以B[1]...B[next[j]] == A[i-next[j]]...A[i-1],这样我们就只需要继续匹配A[i]和B[j+1]而不需要回溯i。

核心代码:

for(int i=2,j=0;i<=m;i++)
{
    while(j&&p[i]!=p[j+1]) j=ne[j];
    if(p[i]==p[j+1]) j++;
    ne[i]=j;
}
for(int i=1,j=0;i<=n;i++)
{
    while(j&&s[i]!=p[j+1]) j=ne[j];
    if(s[i]==p[j+1]) j++;
    if(j==m) 
    {
        //匹配成功
    }
}

如何求B数组的next数组呢?

其实流程是一样的,就是B和B自己的一个匹配。

假设两个相同的字符串B1和B2java kmp 字符串匹配,此时匹配的下标是i和j,并且next[1~i-1]已经算出来了。不断地扩展j直到B1[j] == B2[i] 此时next[i] == j。