文档:字符串匹配算法KMP算法.note
链接:http://note.youdao.com/noteshare?id=bbff1336778f6c391050f4ce4a0bc562&sub=ECF83D03AEF44617A1372BFDF87F5997
package arithmetic;
import java.util.Arrays;
//kmp算法实现
public class kmp {
private int[] next;
public int contain(String targetStr,String pattern) {
int re = -1;
createNextArray(pattern);
System.out.println("next 数组:");
System.out.println(Arrays.toString(next));
int i = 0;//原串索引位置。
int j = 0;//模式串索引位置
while(i < targetStr.length() && j < pattern.length()) {
if(targetStr.charAt(i) == pattern.charAt(j)) {
i++;
j++;
}else if(j == 0) {
//第一个匹配失败直接往下跳继续匹配
i++;
}
else {
j = next[j];//模板串回溯至next 数组指定的位子
}
}
if(j == pattern.length()) re = i-next[0];
return re;
}
//构建next 数组
private void createNextArray(String pattern) {
next = new int[pattern.length()+1];
next[0] = pattern.length();//0号位都装数组长度
//后缀索引
int i = 1;
//前缀索引
int j = 0;
next[1] = 0;
while(i < next[0]) {
if(j == 0 || pattern.charAt(i) == pattern.charAt(j)) {
j++;
i++;
//将匹配的后一个索引对应的next数组值赋值
next[i] = j;
}else {
//回溯 前缀索引j
j = next[j];//直接回溯至对应的next数组的位置,因为next[j]前面的字符与i前面数组都是 相同的,避免多余匹配
}
}
}
public static void main(String[] args) {
kmp kmpTool = new kmp();
String targetStr = "wbabaaaba";
String pattern = "aba";
//kmpTool.createNextArray(targetStr);
//Arrays.toString(kmpTool.next);
System.out.println("匹配位置"+kmpTool.contain(targetStr, pattern)) ;
}
}