public class StringMatching {
public int[] fail = null;//失败函数
//fail[j]只和模式的前j个字符构成有关,而与目标字符串无关
//fail[j]={k, 若k为满足:o<=k<j,且p0p1...pk = pj-k=j-k+1....pj的最大整数
//........{...若k找不到,则=-1;
public int fastFind(String dest, String pat) {
int dpoint = 0;// 目标扫瞄的初始位置
int ppoint = 0;// 模式扫瞄的初始位置
int dsize = dest.length();// 目标字符串的长度
int psize = pat.length();// 模式字符串的长度
if (dsize < 1 || psize < 1 || dsize < psize) {
return -1;
}
caculateFail(pat);
while (ppoint < psize && dpoint < dsize) {
{
if (pat.charAt(ppoint) == dest.charAt(dpoint)) {
ppoint++;
dpoint++;
} else if (ppoint == 0) {// 若第一个字符就匹配失败,从S的下一个字符开始
dpoint++;
} else
ppoint = fail[ppoint - 1] + 1;// 用失败函数确定p就回溯到的字符位置
}
}
if (ppoint < psize) {// 匹配失败
return -1;
}
return dpoint - psize;
}
private void caculateFail(String pat) {
int psize = pat.length();
fail = new int[psize];
// init赋初值
fail[0] = -1;
//计算fail
int i = 0;
for (int j = 1; j < psize; j++) {
i = fail[j - 1];
while (pat.charAt(j) != pat.charAt(i + 1) && i > 0) {
i = fail[i];
}
if (pat.charAt(j) == pat.charAt(i + 1)) {
fail[j] = i + 1;
} else
fail[j] = -1;
// System.out.println("fail[" + j + "] =" + fail[j]);
}
}
}