//KMP算法
public class KMP {
private String pat;
private int[][] dfa;
public KMP(String pat) {
int len = pat.length();
this.pat = pat;
int R =256;
dfa = new int[R][len];
dfa[pat.charAt(0)][0] = 1;
for (int X = 0, j =1;j< len;j++) {
for (int c =0; c < R;c++) {
dfa[c][j] = dfa[c][X];
}
dfa[pat.charAt(j)][j] = j+1;
X = dfa[pat.charAt(j)][X];
}
}
public int search(String txt) {
int N = txt.length();
int M = pat.length();
int i,j;
for (i = 0,j = 0;i < N && j <M;i++) {
j = dfa[txt.charAt(i)][j];
}
if (j == M) return i - M;
else return N;
}
}
//Boyer-Moore算法
public class BM {
private String pat;
private int[] right;
public BM(String pat) {
this.pat = pat;
int M = pat.length();
int R =256;
right = new int[R];
for (int i = 0;i< R;i++) right[i] = -1;
for (int i = 0; i < M; i++) right[pat.charAt(i)] = i;
}
public int search(String txt) {
int i, j,skip;
int M =pat.length();
int N = txt.length();
for (i = 0; i < N - M; i += skip) {
skip = 0;
for (j = M-1;j >= 0;j--) {
if (pat.charAt(j) != txt.charAt(i + j)) {
skip = j - right[txt.charAt(i + j)];
if (skip < 1) skip = 1;
break;
}
if (skip == 0) return i;
}
return N;
}
}
}
//Rabin-Karp算法
public class RK {
private long patHash; // pattern hash value
private int M; // pattern length
private final int R = 256; // radix
private int Q = 997;
private long RM;
public RK(String pat) {
M = pat.length();
patHash = hash(pat, M);
for (int i = 1; i <= M-1; i++)
RM = (R * RM) % Q;
}
private long hash(String pat, int M) {
long h = 0;
for (int j = 0;j < M ;j++) {
h = (R * h + pat.charAt(j)) % Q;
}
return h;
}
public int search(String txt) {
int N = txt.length();
long txtHash = hash(txt, M);
if (patHash == txtHash) return 0;
for (int i = M; i < N;i++) {
txtHash = (txtHash + Q - RM*txt.charAt(i-M) % Q) % Q;
txtHash = (txtHash*R + txt.charAt(i)) % Q;
if (patHash == txtHash) return i - M + 1;
}
return N;
}
}