KMP算法java实现
来源:互联网 发布:linux弱口令扫描工具 编辑:程序博客网 时间:2024/06/05 07:46
一、KMP算法
在数据结构,字符串的操作中,有一个非常重要的方法,即在一个字符串中(主串)搜索一个特定的字符串(子串或模式串),若找到则返回字符串的位置,未找到则返回-1;
最简单的方法则是采用回溯的方法,又叫Brute-Force算法,即从头遍历主串,若与子串第一个字符一样则比对第二个字符串,若不相同则回溯到第一个字符的下一个字符开始重新比较。设主串为
fffff….ffff 模式串为fffff…fffe 。则这种算法的时间复杂都为O(n*m)。
n个f m个字符
编写的JAVA程序如下:
public static int BFIndex(String s,String t){int i=0,j=0;while(i<s.length()&&j<t.length()){if (s.charAt(i)==t.charAt(j)) {i++;j++;}else{i=i-j+1;j=0;}}if(j==t.length()){return i-j;}return -1;}
测试一下,Main函数:
public static void main(String[] args) {String s="aaabaaabaaabaaaab";String t="aaaab";System.out.println(BFIndex(s, t1));}
输出12。
这种方法原理是回溯,时间复杂度过高,所以Knuth、Morris、和Pratt设计了一种算法,叫KMP算法,将时间复杂度下降至O(n+m);
KMP算法的核心在于,模式串中是否有字符串满足
‘p1p2p3…pk-1’=’si-k+1si-k+2…si-1’
若含有则下一次匹配为Si与Pk若不含有,则可直接进行Si和P1的比较。
K的取值只与模式串有关,将每一位的k值计算出来,放入数组中,称之为next数组,通过算法计算这个数组。实际就是求模式串中’p1…pk-1’=’pj-k+1…pj-1’
数组第一位的next值设为0,next[j+1]的值分两种情况,(1)若pk=pj则next[j+1]=next[j]+1=k+1 (2)若pk ≠pj则j=next[j-1]。
还需讨论如s="aaabaaabaaabaaaab" t="aaaab" 这种情况,aaaab对应的next值为01234,但是因为前面四个a都是重复的,所以实际应该为00004,根据这种情况最终编写代码如下:
public static int[] Get_next(String t){int[] next;int i=1,j=0;next=new int[t.length()];next[0]=0;while(i<t.length()){if(j==0||t.charAt(i-1)==t.charAt(j-1)){if(t.charAt(i)!=t.charAt(j)){next[i++]=++j;}else{next[i++]=next[j++];}}else {j=next[j-1];}}return next;}
算法程序如下:
private static int KMPIndex(String s, String t, int[] next) {int i=0,j=0;while(i<s.length()&&j<t.length()){if(s.charAt(i)==t.charAt(j)){i++;j++;}else{j=next[j];if(j==0){i++;}}}if(j<=t.length()){return i-j;}return -1;}
测试程序:
public static void main(String[] args) {String s="aaabaaabaaabaaaab";String t="aaaab";int [] a=Get_next(t);System.out.println(KMPIndex(s,t,a));}
得结果12;
下面分别计算下两个方法所需时间
public static void main(String[] args) {String s="aaabaaabaaabaaaab";String t="aaaab";Long i=System.nanoTime();BFIndex(s, t);Long j=System.nanoTime();System.out.println("BF算法所需时间:"+(j-i)+"ns");Long k=System.nanoTime();int [] a=Get_next(t);KMPIndex(s,t,a);Long l=System.nanoTime();System.out.println("KMP算法所需时间:"+(l-k)+"ns");}
输出
BF算法所需时间:60413ns
KMP算法所需时间:9817ns
源码:
http://download.csdn.net/detail/dongze2/9868277
第一次发文章,欢迎大家批评指正,谢谢
- java实现kmp算法
- KMP算法java实现
- Java实现KMP算法
- KMP算法java实现
- KMP算法----java实现
- KMP算法java实现
- KMP算法Java实现
- KMP 算法 java实现
- Java实现KMP算法
- KMP算法Java实现
- KMP算法java实现
- KMP算法-Java实现
- KMP算法java实现
- KMP算法JAVA实现
- Java实现KMP算法
- KMP算法 Java实现
- KMP算法java实现
- KMP算法java实现
- java使用qq发送邮件
- 廖雪峰的Python-返回函数
- CentOS修改Tomcat端口号
- 贪心之钱币找零问题
- 循环冗余检验CRC(Cyclic Redundancy Check)
- KMP算法java实现
- SpringBoot Junit 测试加载 xml 读取 bean 失败
- fig11_06.cpp
- Java通用与进阶知识,仅用于自身补充
- JAVA高级特性:泛型
- Java多线程之Executor框架
- http(2)
- 335. Self Crossing
- sql语句的优化