关于KMP算法
public class KMP {
public static void main(String[] args) {
/*String str = "ababaaab"; // -1 0 0 1 2 3 1 1
init(str);
for (int i = 0; i < str.length(); i++) {
System.out.print(next[i] + " ");
}*/
String s = "tazbd12a3abdempj";
String t = "abdem";
int count = function(s, t);
System.out.println(count);
}
static int[] next = new int[20];
//next[j]表示当j这个编号所在的元素和主串的元素不匹配,则子串往前回溯到next[j]这个编号,因为next[j]前一个元素或者前几个元素是和主串相等的
public static void init(String str) {
//明确方法目的,这个方法就是为了制造next数组
int i = 0; //int i = 1;
int j = -1; //int j = 0;
next[0] = -1; // next[1] = 0;
while (i < str.length() - 1) {
if (j == -1 || str.charAt(i) == str.charAt(j)) { // j == -1是代表子串中没有元素可以匹配主串当前元素
i++;
j++;
next[i] = j;// 这个很非常重要!!!
//1.表示主串的i元素和子串的j元素相等,如果主串的i+1个元素不能匹配,则就从j+1元素进行搜索匹配
//2.也可能是主串当前元素和子串所有数都不匹配,只能跳过主串的这个元素i++,并且主串的下个元素对应着子串的0(j++)号元素(next[i] = 0)
} else {
j = next[j]; //j往前回溯,进行匹配
}
}
}
public static int function(String s, String t) {
int i = 0;
int j = 0;
init(t);
while(i < s.length()){
if(j == -1 || s.charAt(i) == t.charAt(j)){
i++;
j++;
if(j == t.length())
return i - j;
}else{
j = next[j];
}
}
return -1;
}
}
自身理解
KMP是通过子串元素的重合度进行移动,主串不回溯,子串要回溯与主串元素比较,通过next数组来定位回溯之后j的下标