BF字符串匹配算法

package com.link.string;

/**
 * @Author sunzy
 * @DATE Create in  2019/10/8 9:18
 */
public class StringMatch {
    public static void generalBC(char[] b,int m,int [] bc){
         for(int i=0;i<bc.length;i++){
             bc[i]=-1;
         }
         for(int i=0;i<m;i++){
             bc[(int)b[i]]=i;
         }
    }
    public int bf(char[] source,int n,char[] des,int m){
        int[] bc = new int[256];
        generalBC(des,m,bc);
        //好后缀对应模式串的匹配子串的坐标
        int[] suffix = new int[m];
        //是否后缀子串和模式串匹配
        boolean[] prefix = new boolean[m];
        generateGS(des, m, suffix, prefix);
        int i=0;
        while(i<=n-m){
            int j;
            for(j=m-1;j>=0;j--){
               if(des[j]!=source[i+j])break;
            }
            //完全匹配返回匹配的下标值
            if(j<0){
                return i;
            }
            //坏字符规则
            int badsing=(j-bc[(int)source[i+j]]);
            //好后缀规则
            int goodsuff=moveByGS(suffix,prefix,j,m);
            i = i+Math.max(badsing,goodsuff);

        }
        return -1;
    }

    private int moveByGS(int[] suffix, boolean[] prefix, int j, int m) {
        int suff=m-(j+1);
        if(suffix[suff]!=-1){
            return m-suff-suffix[suff];
        }
        for(int i=suff+1;i>=0;i--){
            if(prefix[i]==true){
                return m-i;
            }
        }
        return m;

    }
    
//计算好后缀
    private void generateGS(char[] des, int m, int[] suffix, boolean[] prefix) {
            for(int i=0;i<m;i++){
                suffix[i]=-1;
                prefix[i]=false;
            }
            for(int i=0;i<m-1;i++){
                int j=i;
                int k=0;
                while (j>=0&&des[j]==des[m-1-k]){
                    k++;
                    suffix[k]=j;
                    j--;
                }
                if(j==-1){
                    prefix[k]=true;
                }
            }
    }

    public static void main(String[] args) {
        char[] source={'a','b','c','a','c','a','b','c','b','c','b','a','c','a','b','c'};
        char[]des={'c','b','a','c','a','b','c'};
        StringMatch stringMatch=new StringMatch();
        int i = stringMatch.bf(source,source.length,des,des.length);
        System.out.println(i);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值