BoyerMoore算法 Java实现

**

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;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值