C++
#include <iostream>
#include <cstring>
int kmp(const char* T, const char* P);
int* buildNext(const char* p);
int main() {
std::cout << kmp("abcaabca", "bca");
}
//构造next表
int* buildNext(const char* p) {
int* N = new int[strlen(p)];
int j = 0;
int t = -1;
N[0] = -1;
while (j < strlen(p)-1) {
if (t < 0 || p[j] == p[t]) {
j++; t++;
N[j] = (p[j] != p[t] ? t : N[t]);//此为改进版,原本为N[j] = t;
}
else
t = N[t];
}
return N;
}
//kmp主算法
int kmp(const char* T, const char* P) {
int i = 0;
int j = 0;
int* next = buildNext(P);
const int n = static_cast<int>(strlen(T));
const int m = static_cast<int>(strlen(P));
while (j < m && i < n) {
if (j < 0 || T[i] == P[j]) {
j++;
i++;
}
else
j = next[j];
}
delete next;
return i - j;
}
Java
public class Main {
public static void main(String[] args) {
System.out.println(kmp("abcabca", "bca"));
}
//kmp主算法
public static int kmp(String T, String P) {
int i = 0;
int j = 0;
int[] next = buildNext(P);
while (j < P.length() && i < T.length()) {
if (j < 0 || T.charAt(i) == P.charAt(j)) {
i++;
j++;
} else
j = next[j];
}
return i - j;
}
//构造next表
private static int[] buildNext(String p) {
int[] N = new int[p.length()];
N[0] = -1;
int t = -1;
int j = 0;
while (j < p.length() - 1) {
if (t < 0 || p.charAt(j) == p.charAt(t)) {
j++;
t++;
if (p.charAt(j) != p.charAt(t)) N[j] = t;
else N[j] = N[t];
} else
t = N[t];
}
return N;
}
}
C++,不用cstring也行
#include <iostream>
template <unsigned N, unsigned M>
int KMP(const char(&T)[N], const char(&P)[M]);
int main() {
std::cout << KMP("abcaabca", "bca");
}
template<unsigned M>
int* buildNext(const char (&P)[M])
{
int* N = new int[M];
int j = 0;
int t = -1;
N[0] = -1;
while (j < M - 1) {
if (t < 0 || P[j] == P[t]) {
j++;
t++;
N[j] = (P[j] != P[t] ? t : N[t]);
}
else
t = N[t];
}
return N;
}
template <unsigned N, unsigned M>
int KMP(const char (&T)[N],const char (&P)[M])
{
int i = 0;
int j = 0;
int* next = buildNext(P);
while (j < M && i < N) {
if (j < 0 || T[i] == P[j]) {
j++;
i++;
}
else
j = next[j];
}
delete next;
return i - j;
}