KMP算法的简单总结以及java代码实现
2016-04-27 11:00
701 查看
KMP研究
参考:/article/1362918.html
做了好几天KMP的题,今天终于写好了,可以总结一下这么多天学到的东西了,结合了众多版本之后觉得还是July写的最好,KMP是一个解决模式串在文本串是否出现过,以及若是出现时,最早出现的位置的经典算法。
首先,这个问题,如果用暴力方法解决的话就会有大量的回溯,每次只移动一位,若是不匹配,移动到下一位接着判断,浪费了大量的时间,所以,kmp方法算法就利用之前判断过信息,通过一个next数组,保存模式串中前后最长公共子序列的长度,每次回溯时,通过next数组找到,前面匹配过的位置,省去了大量的计算时间。
话不多说,上代码:`
运行结果: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)
参考:/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)
相关文章推荐
- Eclipse下进行SVN提交时报“svn: 过期”错误的解决办法
- ElasticSearch学习15_Elasticsearch 口水篇(4)java客户端 - 原生ESClient
- java只使用try和finally不使用catch的原因和场景
- Eclipse 4.5+(Mars)安装SVN
- Spring事务和异常回滚
- Java NumberFormatException详解
- Java基础知识IO流(字节流File读取操作)
- java四种运算符
- 深入理解java嵌套类和内部类、匿名类
- Java性能监控系列——java.lang.instrument
- Struts流程
- 今天晚上 中国互联网被Struts2漏洞血洗
- PAT乙级(Basic Level)真题 >福尔摩斯的约会 (Java记录)
- Struts2理解--动态方法和method属性及通配符_默认Action
- sha1加密java代码
- Java Observable 模式
- java代码实现二叉排序树
- 使用Rxjava缓存请求
- eclipse-4.4.2安装Groovy插件(其他版本eclipse可参考)
- JAVA 判断一个整数是否为2的整数次幂的方法