KMP算法java实现

一、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

测试一下,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

算法程序如下:

	private static int KMPIndex(String s, String t, int[] next) {
		int i=0,j=0;
		while(i


测试程序:

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

第一次发文章,欢迎大家批评指正,谢谢


你可能感兴趣的:(KMP算法java实现)