kmp字符串查询算法
1 普通的字符串查询
普通的字符串查询是遍历被查找的字符串,然后和key字符串进行匹配,如果不一致,则,被查找的字符串+1,继续向下遍历。
代码如下:
private static void search(String str, String key) {
char strArr[] = str.toCharArray();
char keyArr[] = key.toCharArray();
int i = 0, j = 0;
int n = 0;
while (i < strArr.length && j < keyArr.length) {
n++;
if (strArr[i] == keyArr[j]) {
i++;
j++;
} else {
i = i + 1 - j;
j = 0;
}
}
if (j == keyArr.length) {
System.out.println(true);
System.out.println(n);
System.out.println(i - j + 1);
}
}
2 KMP查询
kmp查询的是和普通唯一不同的是i在遍历后发现不同的时候的跳跃的个数不是1。
比较难的是next数组的计算,next数组计算的时候计算的是最长子前缀和最长子后缀的相同字符的数量。
比如,ABABABA,对于第四个字符B,ABAB他的前缀是B BA BAB ,后缀是A BA ABA,所以next[4] = 1。
对于next数组的计算,暂时没有特别明白。
代码如下:
private static void kmpSearch(String str, String key) {
char strArr[] = str.toCharArray();
char keyArr[] = key.toCharArray();
int[] next = getNext(key);
for (int i : next) {
System.out.print(i + ",");
}
int i = 0, j = 0;
int n = 0;
while (i < strArr.length && j < keyArr.length) {
n++;
if (strArr[i] == keyArr[j]) {
i++;
j++;
} else {
i = i + j - next[j];
j = 0;
}
}
if (j == keyArr.length) {
System.out.println(true);
System.out.println(n);
System.out.println("=====================");
System.out.println(i - j + 1);
}
}
public static int[] getNext(String ps) {
int next[] = new int[ps.length()];
char[] p = ps.toCharArray();
next[0] = -1;
int k = -1;
int j = 0;
while (j < ps.length() - 1) {
// p[k]表示前缀,p[j]表示后缀
if (k == -1 || p[j] == p[k]) {
++k;
++j;
next[j] = k;
} else {
k = next[k];
}
}
return next;
}