**
BoyerMoore算法 Java实现
**
今天先是看了KMP算法 接着才知道最高效的是BoyerMoore算法 感觉很巧妙 于是迫不及待地想用Java实现 花了一天的时间 差不多算是成功了 不好的地方应该是没有面向对象 下面把我的代码分享给大家 欢迎批评指正 共同进步
代码
//基本思想:从短字符串的最后以为开始比较
// 定义坏字符与好后缀:
// 坏字符:与短字符串的最后一个字符不匹配 那么长字符串上对应不匹配的字符就是坏字符
// 坏字符后移规则:
// 若该坏字符不包含于短字符串中,那么可知需要将短字符串后移到坏字符的下一位
// 若该坏字符包含于短字符串中,那么将短字符串后移至可以和这个坏字符对齐的位置
//
// 好后缀:所有尾部匹配的字符串(与KMP算法类似)
// 好后缀后移规则:后移位数为 好后缀出现的位置-搜索词中上一次出现的位置
//
// 每次后移的位置为 两次规则的后移位数的最大值
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class C2字符串匹配算法之BoyerMoore算法 {
public static void main(String[] args) {
String s1 = "here is a simple example";
String s2 = "example";
System.out.println(stringmatch(s1,s2));
}
public static boolean stringmatch(String s1, String s2){
int len1 = s1.length();
int len2 = s2.length();
int s = 0;//已匹配的字符的个数
int i = len2-1;
int j = len2-1;
while (j >= 0 && i < len1){
if (s1.charAt(i) == s2.charAt(j)){
j--;
i--;
s++;
if(s == len2){
return true;
}
}else{
int step1 = 0;//坏字符后移位数
int step2 = 0;//好后缀后移位数
int step = 0;//比较坏字符规则与好后缀规则后 选择的后移最大值
//坏字符规则:
int k = len2-s-2;
int c = 0;
//判断这个坏字符有没有在短字符串没有比较的部分出现过
while(k >= 0){
// 如果出现过,则将二者对齐
if(s2.charAt(k) == s1.charAt(i)){
step1 = len2 -1 -k;
c++;
}
k--;
}
// 如果没有出现过,则将段字符串移到这个坏字符的后面
if(c == 0){
step1 = len2;
}
//好后缀规则:
int h = len2-s-1;
int g = len2-1;
//当短字符串的后面已经由一小段与长字符串匹配 分别从已被匹配的最后一位 和 未被匹配的最后一位 开始
while (h >= 0 && g >= len2-s){
//判断没有匹配的部分是否有与已匹配部分重合的
if(s2.charAt(h) == s2.charAt(g)){
// 如果前面有一段与已匹配的部分重合,将没有被匹配的这一段与长字符串对齐
if(g == len2-s){
step2 = len2-h-s;
// 如果是从短字符串的开头,有一部分与已匹配的部分重合,将短字符串从头开始与长字符串的已被匹配的部分对齐
}else if(h == 0){
step2 = len2-1+s;
// 其他情况说明短字符串没有被匹配的部分,也不可能与已被匹配的长字符串对齐,因此短字符串要向后移动自身的长度
}else{
step2 = len2;
}
h--;
g--;
}else {
//如果未被匹配的部分的这一位 没有与已被匹配的部分对应位置匹配 将未被匹配的位置前移一位
h--;
g = len2-1;
}
}
//将匹配成功的个数清零 以免影响下一次判断
s = 0;
//选择两个规则的最大步数
step = Math.max(step1, step2);
j = len2-1;
i = i +step;
}
}
return false;
}
}