Brute-Force:

其基本思路是:从目标串s=”s0s1…sn-1”的第一个字符开始和模式串t=”t0t1…tm-1”中的第一个字符比较,若相等,则继续逐个比较后续字符,否则,从目标串s的第2个字符开始重新与模式串t的第一个字符进行比较,依次类推,若从目标串s的第i个字符开始,每个字符依次和模式串t中的对应字符相等,则匹配成功,该算法返回i;否则匹配失败,返回-1。

//Brute-Force算法
public class BruteForce {
  
	public static int bruteForce(String src,String sub)
	{
		int i=0,j=0,index=-1;
		while(i<src.length()&&j<sub.length())
		{
			if(src.charAt(i)==sub.charAt(j))
			{
				i++;
				j++;	
			}
			else
			{
				i=i-j+1;
				j=0;
			}
		}
		
		if(j==sub.length())
		{
			index = i-sub.length();
		}
		
		return index;
	}
}

该方法的优点是:算法简单明朗,便于实现记忆。

缺点是:进行了回溯,效率不高,而这些都是没有必要的。


KMP算法:

//KMP算法
public class KMP {

	//根据给定的模式串,求next[j]的算法
	public static int[] getNext(String sub)
	{
		int j=1,k=0;
		int[] next = new int[sub.length()];
		next[0]=-1;
		next[1]=0;
		
		while(j<sub.length()-1)
		{
			if(sub.charAt(j)==sub.charAt(k))
			{
				next[j+1]=k+1;
				j++;
				k++;
			}
			else if(k==0)
			{
				next[j+1]=0;
				j++;
			}
			else
			{
				k=next[k];
			}
		}
		return next;
	}
	
	//根据给定主串和子串,采用KMP算法
	public static int kmp(String src,String sub)
	{
		//先生成模式串sub的next[j]
		int[] next = getNext(sub);
		
		//i:主串的游标
		//j:子串的游标
		int i=0,j=0,index=-1;
		while(i<src.length()&&j<sub.length())
		{
			if(src.charAt(i)==sub.charAt(j))
			{
				i++;
				j++;
			}
			else if(j==0)
			{
				i++;
			}
			else
			{
				j=next[j]; //向右滑动
			}
				
		}
		if(j==sub.length())
		{
			index = i-sub.length();
		}
		return index;
	}
}

KMP算法的实现:关键一点是求next函数以及算法的主串是一直向前行进的,无需回溯。

next函数的实现:是一个递推的过程,j游标也不回溯,两个游标分别为j和k,j是主要游标,k在后面跟随。因为真子串的前后都是一样的,所以可以直接借到后面的j游标处,中间可以跨过。

中间会有重复的地方吗?

答:不会有,如果有的话有且只有最大真子串。可以自行画图推断。

next函数的作用是求出最大的真子串,从而可以跨过相同区。

KMP函数:其最大的特点是无回溯,在不同时,只需用next函数找到真子串即可,因为真子串前后表相同。


参考博客链接:http://www.cnblogs.com/goagent/archive/2013/05/16/3068442.html