KMP算法的简单总结以及java代码实现

KMP研究
参考:http://blog.csdn.net/v_july_v/article/details/7041827
做了好几天KMP的题,今天终于写好了,可以总结一下这么多天学到的东西了,结合了众多版本之后觉得还是July写的最好,KMP是一个解决模式串在文本串是否出现过,以及若是出现时,最早出现的位置的经典算法。
首先,这个问题,如果用暴力方法解决的话就会有大量的回溯,每次只移动一位,若是不匹配,移动到下一位接着判断,浪费了大量的时间,所以,kmp方法算法就利用之前判断过信息,通过一个next数组,保存模式串中前后最长公共子序列的长度,每次回溯时,通过next数组找到,前面匹配过的位置,省去了大量的计算时间。
话不多说,上代码:`

public class KMP {
    public static int kmp(String str, String dest,int[] next){//str文本串  dest 模式串
        for(int i = 0, j = 0; i < str.length(); i++){
            while(j > 0 && str.charAt(i) != dest.charAt(j)){
                j = next[j - 1];
            }
            if(str.charAt(i) == dest.charAt(j)){
                j++;
            }
            if(j == dest.length()){
                return i-j+1;
            }
        }
        return 0;
    }
    public static int[] kmpnext(String dest){
        int[] next = new int[dest.length()];
        next[0] = 0;
        for(int i = 1,j = 0; i < dest.length(); i++){
            while(j > 0 && dest.charAt(j) != dest.charAt(i)){
                j = next[j - 1];
            }
            if(dest.charAt(i) == dest.charAt(j)){
                j++;
            }
            next[i] = j;
        }
        return next;
    }
    public static void main(String[] args){
        String a = "ababa";
        String b = "ssdfgasdbababa";
        int[] next = kmpnext(a);
        int res = kmp(b, a,next);
        System.out.println(res);
        for(int i = 0; i < next.length; i++){
            System.out.println(next[i]);            
        }
        System.out.println(next.length);
    }
}

运行结果:9
0 0 1 2 3 5
其实kmp算法的核心代码就几行而已
在匹配阶段,若是模式串和文本串相同,那就继续匹配下一位,若是不相同,就去找next数组记录的位置,继续匹配,这个也是kmp算法和普通暴力算法的主要区别,暴力是从头开始匹配,而kmp通过next数组,发现前面可以跳过大量重复计算的东西。
下面讲一下,next数组的计算方法:
next数组的计算主要跟模式串有关,与文本串并没有关系,因为,模式串前后公共最长子序列。这样才会让我们跳过大量的重复计算
next数组的主要实现方法有很多,就是要找到前后最长公共子序列的长度 比如:
ababa:
模式串的各个子串: 前缀: 后缀: 最大公共元素长度
a 0
ab a b 0
aba a ab a ba 1
abab a ab aba b ab bab 2
ababa a ab aba abab a ba aba baba 3
如上图,next数组中的元素就是 0 0 1 2 3 ;
所以,kmp算法的核心就是计算next数组。理解到这里,就明白kmp算法了,就不会看一次忘一次了!
kmp算法的核心时间复杂度就是O(m+n)

你可能感兴趣的:(java,算法,kmp,剑指offer)