KMP算法

字符串匹配算法之KMP

  1. KMP算法最主要的地方是求next数组,next数组保存的是当前失配节点(下标index)之前的子串subString,求出subString的所有前缀子串后缀子串中长度最长的值value,再将该值保存到next[index] = value。

  2. 代码实现(java版本)

    class KMPDemo{
        public static int KMP(String mainString, String subString){
            int m = mainString.length();
            int n = subString.length();
            
            char[] a = mainString.toCharArray();
            char[] b = subString.toCharArray();
            
            int[] next = getNext(subString);
            int j = 0;
            
            for(int i = 0; i < m; i++){
                while(j > 0 && a[i] != a[j]){
                    //如果当前字符不匹配,则j需要回到j之前的子串中,
                    //最长前缀和后缀子串的长度的下一个字符。
                    j = next[j - 1] + 1;
                }
                
                if(a[i] == b[j])
                    j++;
                if(j == n)
                    return i - n + 1;
            }
            return -1;
        }
        
        public static int getNext(String str){
            int len = str.length();
            char[] ch = str.toCharArray();
            int k = -1;
            
            int[] next = new int[len];
            next[0] = -1;
            
            for(int i = 1; i < len; i++){
                while(k > -1 && ch[k + 1] != ch[i]){
                /* 
                 * 开始时k的值为字符串的[0:i-1]子串的最长相同前缀和后缀子串的长度,
                 * 当之前的i加一后变成现在的i(即上面的i-1 ---> i)后,
                 * 当ch[k+1] != ch[i]时,
                 * 需要将k更新为前k个字符的最长相同前后缀子串的长度值,
                 * 所以 k = next[k]
                 */
                 k = next[k]; 
                }
                
                if(ch[k + 1] == ch[i])
                    k++;
                
                next[i] = k;
            }
            
        }
    }
    

你可能感兴趣的:(KMP算法)