package arithmetic;
import java.util.*;
public class KMP {
public static void main(String args[])
{
System.out.println(KMP("aabaababaabab","ab"));
}
public static int[] next(String parttern)
{
int next[] = new int[parttern.length()+1];
int j =-1;
int i =0;
next[0]=-1;
while(i<parttern.length())
{
if(j==-1||parttern.charAt(i)==parttern.charAt(j))
{
next[++i]=++j;
}else
j=next[j];//next[j]为上一个匹配的位置,即如果 s[i]!=s[j],就将J退回到上一个匹配的位置,直到退到与 parttern.charAt(i)相等为止或 j=-1
}
return next;
}
/*
*
* 上面代码中为什么j的跳变为 j = next[j]
*
* 因为要想保持 pattern 的前部与后部相同的最大化,
* */
public static int KMP(String str,String parttern) //找出第一个就会停止
{
int next [] = next(parttern);
int i =0,j=0;
while(i<str.length()&&j<parttern.length())
{
if(j==-1||str.charAt(i)==parttern.charAt(j))
{
i++;j++;
}
else
j=next[j];
//可以在这里判断是否已经全部匹配,如果全部匹配,可以将其(i-j)位置保存起来,查找全部匹配位置
//再将j =0 即可
}
return j==parttern.length()?(i-j):-1;
}
}
/*
* KMP 算法
* 总结:遍历匹配串,不断更新从开始到当前字符 i 可以与模式串中匹配的位置
* 如果 A[i] ==B[j]
* 那么 i++;j++;
* 如果A[i]==b[j]
* 则 j =next[j]
* */
/*
* 求NeXt 方法
* 遍历 匹配串,不断更新可以使开始到当前字符i 头部尾部相当的最大的J的位置
*
* 如果 pattern[i]==pattern[j]
* 则 i++;j++;next[i] =j
* 否则(下面就要缩小j的范围,因为不光1-j 的头部与尾部相同,可能在J之前还有与尾部相同的,只不过是它们比J小,所以先判断的J的值,而J不满足,那么我们就得考虑J前面的值了)
* j = next[j] 因为next[J]里面保存是存在首部和尾部相同的位置,所以j=next[j]
* */
//参考:http://www.matrix67.com/blog/archives/115
KMP 算法
最新推荐文章于 2023-04-09 17:43:52 发布