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);
}
}
BF字符串匹配算法
最新推荐文章于 2020-10-26 22:50:50 发布