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
转载于:https://blog.51cto.com/wukong0716/1688037