字符串得模式匹配算法:BF,KMP,BM以及Sunday算法

字符串得模式匹配操作:BF,KMP,BM以及Sunday算法



介绍

模式匹配

模式串(字符串),要在另一个主串中查找是否存在与模式串相等的子串(主串中任意连续字符组成的子序列)

BF算法

最简单最暴力

KMP算法

值得深入研究得算法。其中next数组的求值是理解kmp算法的关键。

public class KMP {
    /**
     *
     * @param source 源字符串
     * @param target 目标字符串
     * @return
     */
    public static int indexOf(String source,String target){
        char[] s = source.toCharArray();
        char[] t = target.toCharArray();
        int tLen = t.length;
        int[] next = new int[tLen];
        get_next(target,next);//计算next数组
        int sLen = s.length;
        int i = 0;// 原字符串下标
        int j = -1;// 目标字符串下标
        // 核心i一直向前比较,不会回溯。只回溯j
        while(i<sLen && j<tLen){
            if(j ==-1 || s[i] == t[j]){
                i++;
                j++;
            }else {
                j = next[j];
            }
        }
        if(j == tLen){
            return i-j;
        }else {
            return -1;
        }
    }

    /**
     * next数组得计算
     * @param target 目标子窜
     * @param next  next数组
     */
    public static void get_next(String target,int[] next){
        char[] t = target.toCharArray();
        int tLen = t.length;
        next[0] = -1;
        int k = -1;
        int j = 0;
        while(j<tLen-1){
            if(k==-1 || t[j] == t[k]){ //target[j]后缀,target[k]前缀。 
                k++;
                j++;
                if(t[j] != t[k]){
                    next[j] = k;
                }else{
                    next[j] = next[k];
                }
            }else {
                k = next[k];
            }
        }
    }

    public static void main(String[] args) {
        String source = "avcsdfadfa";
        String target = "dfa";
        System.out.println("出现位置"+indexOf(source, target));
    }

}

BM算法

很专业!

SunDay算法

public class SunDay {
    public static void main(String[] args) {
        System.out.println("出现位置:"+sunday("abcxedadxesafaa", "xes"));
    }
    public static int sunday(String source,String target){
        char[] s = source.toCharArray();//源字符数组
        char[] t = target.toCharArray();//匹配数组
        int sLen = s.length;
        int tLen = t.length;
        int i = 0;
        int j = 0;
        while(i <= sLen-tLen){
            while(j < tLen && s[i+j] == t[j]){
                j++;
            }
            if(j==tLen){
                return i;
            }
            //不匹配时,求出跳过得字符数
            if(i<sLen-tLen){
               i += (tLen-lastIndex(t,s[i+tLen]));// 由lastIndex算出该字符出现得最后位置。使用tLen-该位置得到i应该抵达得位置。此时重新开始比较
            }else {
                return -1;
            }
            j = 0;
        }
        return -1;
    }

    public static int lastIndex(char[] t,char c){
        for(int i = t.length-1;i>=0;i--){
            if(t[i] == c ){
                return i;
            }
        }
        return -1;
    }

}

值得研究博客推荐:
http://www.ruanyifeng.com/blog/2013/05/boyer-moore_string_search_algorithm.html
https://blog.csdn.net/v_JULY_v/article/details/7041827

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值