字符串匹配——KMP算法的Java实现
来源:互联网 发布:linux arp防火墙关闭 编辑:程序博客网 时间:2024/06/04 21:01
开始复习算法,复习到字符串这一结构时,一个经典的问题就是两个字符串的匹配问题。
比如:在主串ssdfgasdbababa
中找是否存在一个asdba
的子串。
传统方法——暴力匹配
用传统的方法就是暴力匹配,从主串中一个个地和子串匹配。
最坏的情况下,就是匹配到最后一步才得到结果。
其时间复杂度为O((m-n)*n)
,其中主串的长度为m,子串的长度为n。
KMP算法
以下为自己的理解,表达上难免有些口语化:)
KMP算法的核心思想就是:如果A==B,B!=C,那么A必然不等于C!,这样一来就省掉了比较A和C的步骤。
KMP的大致思想就是:利用一个next数组,保存子串中每个字符前面的前缀和后缀的最大相同匹配长度,为了在与主串匹配时,如果存在相同的部分,就可以通过next数组来“跳过”已经相同的部分,省掉一些匹配操作。。
如果想看详细解释,推荐另一篇博客:KMP算法最浅显理解——一看就明白,不过提醒下这篇是基于C++实现的,不过原理讲的挺好的。
代码实现与理解
在KMP算法上分两部分:一部分是计算next数组,另一部分就是子串和主串匹配。其实两者实现原理是一致的。
计算next数组
首先计算子串的next数组
在这里要解释下,不同版本的KMP算法虽然原理一样,但是各自对next的值有不同的理解,在这里说明一下,next数组中:
- 为0:代表前缀和后缀没有匹配的,同时默认子串第一个元素的next值为0,比如
abc
每个字符的next值都为0; - 为1:代表前缀和后缀有一个字符匹配的,比如
aba
中,最后一个字符a
的next值为1; - 为2:代表前缀和后缀有两个字符匹配的,比如
abab
中,最后一个字符b
的next值为2; - 以此类推3,4,5······
public static int[] calNext(String str){ int length = str.length(); //子串的长度 int j = 0; //j是next数组的下标 int[] next = new int[length]; //初始化子串 next[0] = 0; //子串的第一个元素肯定没有匹配的,默认为0 for(int q = 1; q<length; q++){ while(j>0 && str.charAt(j)!=str.charAt(q)){ //如果不相等 //j下标表示next数组的index,q下标表示子串的index //j>0说明前面仍有部分匹配的情况 //注意:在next数组中next[j]永远小于或等于j的,保证当不相等的情况下,够往前回溯 j = next[j-1]; //回溯 } if (str.charAt(q)==str.charAt(j)) { //如果相同,则j加1 j++; } next[q] = j; } return next; }
利用next数组,匹配主串和子串
KMP主方法思想和上面求next数组思想是一致的,只不过一个是串内匹配,这个是两个串之间匹配。
直接上代码:
//str为主串,dest为子串,next为上面得到的next数组public static int kmp(String str, String dest, int[] next){ for(int i=0,j=0;i<str.length();i++){ while(j>0&&str.charAt(i)!=dest.charAt(j)){ //说明子串和主串当前下标的元素不匹配 //j>0说明前面有相同的部分 j = next[j-1]; //回溯 } if(str.charAt(i)==dest.charAt(j)){ j++; } if(j == dest.length()){ //说明匹配到了子串末端,找到匹配的地方 return i-j+1; } } return -1; //如果找不到匹配,返回-1 }
主程序
最后就是在主程序中调用了。
public static void main(String[] args) { // TODO Auto-generated method stub String str = "ssdfgasdbababa"; String dest = "ababa"; int[] next = calNext(dest); System.out.println(kmp(str, dest, next)); }
总结
当时理解KMP算法还是有点绕,稍微有些难度(原谅我算法基础不咋样~)
最后说一下,KMP算法在字符串存在部分匹配才会体现它的效率,否则和一般方法区别不大。
阅读全文
0 0
- 字符串匹配——KMP算法的Java实现
- 字符串匹配算法KMP Java实现
- 字符串匹配:KMP算法之JAVA实现
- KMP字符串匹配算法Java实现
- KMP字符串模式匹配算法Java实现
- java实现字符串的一般和KMP模式匹配算法
- 字符串匹配—KMP算法
- 字符串匹配的KMP算法实现
- kmp算法实现的字符串匹配
- C++实现字符串匹配的KMP算法
- Golang实现的KMP字符串匹配算法
- KMP字符串匹配算法的分析实现
- 字符串模式匹配的KMP算法实现
- 字符串匹配问题——求给定字符串的next数组以及KMP算法实现
- 字符串匹配问题——KMP算法实现
- kmp字符串匹配算法实现
- 字符串匹配KMP算法实现
- KMP字符串匹配算法实现
- 轮播图
- 大话设计模式读书笔记之抽象工厂
- 11周 项目1
- 第10周【项目2
- 使用谷歌guava之ImmutableMap的好处
- 字符串匹配——KMP算法的Java实现
- recycler视频播放
- ImagesUtils——三级缓存和二次采样
- 数据库系统概念(引言)笔记
- Unity快速集成ShareSDK实现分享和授权登录
- 综合——用Angular和js实现排序查询操作
- 判断t1树是否有与t2树拓扑结构完全相同的子树
- Swoole 实例三(Timer定时器)
- 如何清除Eclipse中SVN用户