Next数组(F数组)

由KMP算法中了解到的,此处作为理解原理的记录

1:KPM算法主要是用于在已知的字符串中寻找子字符串的算法。其基本可以理解为对于朴素的模式匹配的优化。朴素的模式匹配就是我们使用子字符串去逐个回溯进行匹配。而KPM的优化就在于我们降低了子串回溯的次数,进一步明确子串回溯的位置。而字串回溯的位置优化就会引入一个新的数组,Next数组(F数组)。

2:Next数组

        首先可以确定地就是其第一位和第二位的Next数组的值必为0和1

在这里插入图片描述

         接下来寻找第三位的a的Next值,而第三位的前一位是b,b所对应的Next数组的值是下标为1的字符,对应的为a,而a和b不相等,也就是第二位的b和其next数组对应的字符不同所以继续往前找,而往前找不到了,所以第三位a的Next数组的值为1。

        第四位b的Next数组寻找,b的前一位为第三位的a,而第三位的a的next数组的值为1,对应下标为1的字符为a,两者相等,因此第四位的Next数组为在此前1的基础上加1,也就是2。

        第五位aNext数组的寻找,其前一位为第四位的b,对应的Next数组的值为2,而下标2所对应的字符为b,两者相等,因此第五位的Next的值是在第四位next的值的基础上加一,也就是3。

        第六位aNext数组的寻找,其前一位为a,所对应的Next值为3,下标为3 对应的字符为a,两者相同,因此第六位的Next是在地五位的Next基础上加一,为4。

        第七位的a的Next数组寻找。其前一位为a,Next数组为4,对应下表处的字符为b,两者不相同。那么就从第六位的next数组所对应下标处指向了第四位的b,而这个b对应的Next为2,也就是b,而此时b和第六位的a不同,因此我们需要继续往前寻找,从第四位的b的next,找到了第二位的b,而第二位的b 的Next数组为1,对应的是a,与第六位的a实现相等,因此第七位的next为下标为2的Next数组的值加一,也就是1+1=2。所以第七位的Next数组的值为2。

        第八位的b的Next数组。其第七位的a所对应的Next数组的值为2,对应的为下标为2 的b,而a和b不同,因此需要继续往前寻找,当我们走到下标为2的b的时候发现其next的值为1,对应的是a,想同,因此第八位的next的值就是在下标为2的字符的next的值的基础上加一,也就是2。

然后依次求解即可。我们就会得到该字符串对应的next数组。

附:KMP算法的java代码

public static boolean kmp(String str,String s){
        char[] T = str.toCharArray();
        char[] S = s.toCharArray();
        //定义next数组,next数组是根据短串生成的,别搞错了。
        //因为索引0没用到,因此数组长度加1
        int[] next=new int[s.length()+1];
        //定义两个指针
        int j=1;
        //表示前面j-1位置的next数组的值
        int k=0;
        //定义next[1]=0,next[1]=0表示短串已经回溯到头了,此时应该移动长串
        next[1]=0;
        //生成next数组,生成next数组的思路在图中详细解释
        while(j<s.length()){
            if(k==0||S[j-1]==S[k-1]){
                next[++j]=++k;
            }else {
                k=next[k];
            }
        }
        int i=1;
        int l=1;
        while (i<=T.length&&l<=S.length){
            //如果匹配成功,长串短串依次加1。
            //如果匹配失败,短串用next数组回溯,如果回溯到next[1]=0时,l=0,此时表示短串回溯到头了,
            //短串不能再回溯了,长串应该往后一位了(对应情况:如果第一位都不匹配,next[1]=0,长串应该后移一位)
            if(l==0||T[i-1]==S[l-1]){
                i++;
                l++;
            }else {
                l=next[l];
            }
        }
        //l>S.length说明上面的while循环是短串遍历完跳出来的,对应匹配成功的情况
        if(l>S.length){
            return true;
        }else {
            return false;
        }
    }
 

扩展:KMP算法的核心。下章扩展KMP算法

猜你喜欢

转载自blog.csdn.net/qq_42218220/article/details/128791033