算法5.7 Boyer-Moore字符串查找
算法描述
- BM查找是在允许回退时,从右向左扫描pat检查是否与txt匹配,并在匹配失败时通过跳跃将文本中字符和它在pat中出现的最右位置对齐
实现
- 跳跃表right[]:该数组记录字母表中每个字符在pat中最靠右出现的位置,当不存在记为-1,该记录表示当匹配失败时pat应该向右跳跃几位
public BoyerMoore(String pat){
this.pat = pat;
int R = 256;
int M = pat.length();
right = new int[R];
for (int c = 0; c < R; c++)
right[c] = -1;
for (int j = 0; j < M; j++)
right[pat.charAt(j)] = j;
}
- 查找:i,j分别为txt和pat指针,若j从M-1到0循环,txt.charAt(i+j)和pat.charAt(j)都相等,则匹配成功,否则失败
- 失败字符不在pat中:则将pat右移j+1位(通过i增加j+1实现),重置j为M-1
- 失败字符在pat中:则将pat右移直到该字符和其在pat中最右边位置对齐
- 当需要左移时:至少让i+1,右移一位
public int search(String txt){
int N = txt.length();
int M = pat.length();
int skip;
for (int i = 0; i < N; i += skip){
skip = 0;
for (int j = M-1; j >= 0; j--){
if (txt.charAt(i+j) != pat.charAt(j)){
skip = j - right[txt.charAt(i+j)];
if (skip < 1) skip = 1;
break;//当前字符匹配失败
}
}
if (skip == 0) return i;//找到匹配
}
return N;//匹配失败
}
public class BoyerMoore {
private int[] right;
private String pat;
public BoyerMoore(String pat){}
public int search(String txt){}
}
算法分析
- 长N的txt和M的pat,是哟BM算法需要~N/M次比较
证明:跳跃使得几乎所有比较都会跳过M个字符