部分匹配表
前缀=后缀的个数
如“bread”,前缀 b,br,bre,brea,bread;后缀d,ad,ead,read,bread
匹配规则
public class Match {
public static void main(String[] args) {
String str2 = "ACACABAC";
String str1="ABCDACACACACABAC";
int[] ints = kmpMatch(str2);
int i = kmpSearch(str1, str2, ints);
System.out.println(Arrays.toString(ints));
System.out.println(i);
}
public static int violenceMatch(String str1, String str2) {
char[] s1 = str1.toCharArray();
char[] s2 = str2.toCharArray();
int i = 0;
int j = 0;
while (i < s1.length && j < s2.length) {
if (s1[i] == s2[j]) {
i++;
j++;
} else {//j!=0表明匹配已开始,匹配中途s1[i]!=s2[j],需将i倒退j个单位,再向后一个单位,开始下一轮匹配
i = i - j + 1;
j = 0;
}
}
if (j == s2.length)
return i - j;//第一个元素匹配上的位置
else return -1;
}
public static int[] kmpMatch(String dest) {
int[] match = new int[dest.length()];
match[0] = 0;
for (int i = 1, j = 0; i < dest.length(); i++) {
while (j > 0 && dest.charAt(i) != dest.charAt(j)) {
j = match[j - 1];
}
if (dest.charAt(i) == dest.charAt(j))
j++;
match[i] = j;
}
return match;
}
public static int kmpSearch(String str1, String str2, int[] match) {
int i=0;//遍历str1的指针
int j=0;//遍历str2的指针
while (i<str1.length()&&j<str2.length()){
while (j > 0 && str1.charAt(i) != str2.charAt(j)) {//不匹配时重新定位j
j = match[j - 1];
}
if (str1.charAt(i) == str2.charAt(j))
j++;
if (j == str2.length())//匹配完成
return i - j + 1;
i++;
}
return -1;//没找到
}
}