您的位置:首页 > 编程语言 > Java开发

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

2016-04-27 11:00 701 查看
KMP研究

参考:/article/1362918.html

做了好几天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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: