参考网址
https://www.youtube.com/watch?v=GTJr8OvyEVQ
https://blog.csdn.net/christ1750/article/details/51259425
B站视频目前正在审核,所以提供下我的B站账号: 少年的神 没法访问的可以去我B站视频找下。
构建前缀表
最主要的还是要构建一个前缀表,然后在匹配错误的地方按照上一个字母前缀表的下标再去判断是否相等,相等则前缀表+1作为其前缀,不相等则再取其前缀表往前直到第一个比较不相等后则前缀表赋值为0。(注意最后一个的前缀)
比较目标字符串是否在当前字符串中
其实就是循环当前字符串,当当前字符串值第一次等于目标字符串的第一个字母时开始比对下一个,如果下一个不相等就取其前一个的前缀表对应的值再对比,直到相等。
代码
用来存放值的实体类
public class Enity { private char x; private int index;
public char getX() { return x; }
public void setX(char x) { this.x = x; }
public int getIndex() { return index; }
public void setIndex(int index) { this.index = index; }
@Override public String toString() { return "值为"+getX()+"==========="+getIndex()+"\n"; } } |
实现KMP算法的工具类
import java.util.ArrayList; import java.util.List;
public class KmpUtil { private KmpUtil(){
}
/** * * @param s 需要得到前缀表的字符串 * @return * j i * S a b c d * (index) 0 0 */ public static List<Enity> getPreTable(String s){ List<Enity> result = new ArrayList<>(); char[] strs=s.toCharArray(); // 将值赋值到对应的实体类 for (int i=0;i<s.length();i++){ Enity enity = new Enity(); enity.setX(strs[i]); result.add(enity); } //此处开始给实体配置前缀表 result.get(0).setIndex(0); int j=0; for(int i=1;i<result.size();i++){ // 这里获取j值得方法是获取前一个的前缀表值, // 如果和i的值还是不等就再取前一个的前缀值, // 直到相等后取j+1作为前缀值。或者j=0后依然 // 不相等则取前缀值为0 while (j>0&&result.get(j).getX()!=result.get(i).getX()){ j=result.get(j-1).getIndex(); } if (result.get(j).getX()==result.get(i).getX()){ j++; } result.get(i).setIndex(j);
} System.out.println("得到的前缀表:\n"); System.out.println(result.toString()); return result; }
/** * * @param str 判断是否包含dest的字符串 * @param dest 目标字符串 * @return * * i * str a b c d * * destr b c * (index)j */ public static boolean isInclude(String str,String dest){ System.out.println("开始进行对比"); char[] strs=str.toCharArray(); List<Enity> resultList = getPreTable(dest); for (int i=0,j=0;i<str.length();i++){ /** * 这里和上面一个循环差不多 */ while(j>0&&strs[i]!=resultList.get(j).getX()){ j=resultList.get(j-1).getIndex(); } if(strs[i]==resultList.get(j).getX()){ j++; } //如果j等目标字符串长度说明已经全部比对过一遍说明有该值存在 if (j==dest.length()){ return true; //如果还想要继续比对看是否还有 // 这里将j设置为最后一个的前缀值就可以继续获取下一个符合的位置 } } return false; }
} |
测试方法
System.out.println(KmpUtil.isInclude("fabadfadsfadfa","&")); |