KMP算法实现逻辑讲解

参考网址

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","&"));

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值