public class TestClass {
public static void main(String[] args) throws Exception {
String param = "abcabcdefabcabcf";
String string="abciepeiabcabeioabcabcdeioabcabcdefabcabcfabcipwkow";
int[] next = getNext(param);
for(int i:next){
System.out.print(i+" ");
}
int index = findIndex(string, param, next);
System.out.println("\nindex="+index);
System.out.println(string);
int end = index+param.length();
for(int i=0;i<string.length();i++){
if(i>=index && i<end){
System.out.print(string.charAt(i));
}else {
System.out.print("-");
}
}
}
/**获取next数组
* @param string 模式串
* @return
*/
public static int[] getNext(String string){
int count=0;//对获取next数组没用,用来统计获取next数组所要的时间代价
int lenght = string.length();
int[] next = new int[lenght+1];//利用比较巧妙的设计,方便生成next数组和查找匹配,下标为0是没用的,真正的数据从下标1开始
int k=0;//当前next的值
for(int i=1;i<lenght;i++){//由于第一个字符肯定为0,所以从1开始
while(k>0 && string.charAt(i)!=string.charAt(k)){//当不相等时
/*假设:
* string:abcabcdefabcabcf
* next :0000123000123456?
* 由上面可以看到,当最后一个f和下标为7的d(即abcabc'd')不相等时,
* 当前的k为6(即倒数第二个c的next值),通过k=next[k],现在k=3,
* 这里就发现前3个abc,和倒数第4到倒数第2也是abc,这时如果正序第四个字符(即a)和最后一个字符f相等,
* 那么最后一个字符f的next值就是k++(就是4),但是现在不相等,所以继续回退。k=next[3],k就为0了。
*
*
*
*/
k=next[k];//回退到上一次匹配的地方
count++;
}
if(string.charAt(i)==string.charAt(k)){//如果相等,等k+1
k++;
}
next[i+1]=k;//因为next数组是从1开始,所以i要先+1才能对应上
count++;
}
System.out.println("count="+count);
return next;
}
/**长出第一次出现的下标位置
* @param string 长串
* @param param 短串,模式串
* @param next next数组
* @return
*/
public static int findIndex(String string,String param,int[] next){
int count = 0;
int j=0;
int i=0;
int index=-1;
int len1 = string.length()-param.length();
while(i<len1){
count++;
if(string.charAt(i+j)==param.charAt(j)){
j++;
}else{
i+=j-next[j];
j=next[j];
if(j==0){
i++;
}
}
if(j>=param.length()){
index=i;
break;
}
}
System.out.println("\ncount="+count);
return index;
}
}
运行结果: