package com.zcj.alogrithm;
import org.omg.DynamicAny.DynAnyFactoryPackage.InconsistentTypeCode;
//kmp算法
//kmp算法的思想就是尽量减少重复匹配,尽可能的保存中间匹配结果
//过程:对需要查找的子串进行预处理
//前缀和后缀 ababd
//最长匹配前缀和后缀:这里以上面d位置来讲,它的最长匹配前缀和后缀长度为2
//计算前缀过程,以a开头但是不能包含d的前面一个字符即为b
//计算后缀过程,以b结尾向前找,但是不能包含最开头的字符a
//前缀和后缀可以有重叠的部分 可以找到匹配结果为ab和ab
//求解next数组,就是对ababd这个字符串的每个位置进行最长匹配前缀和后缀的求解
//第一个位置规定为-1,第二个位置即为b,显然是0
//总的代码实现如下
public class KMP {
public static void main(String[] args) {
String s1="adbadcdccccca";
String s2="cdc";
int index =compare(s1,s2);
if(index!=-1){
System.out.println("true!");
}else{
System.out.println("false!");
}
}
//匹配过程
private static int compare(String s1, String s2) {
char[] ss=s1.toCharArray();
char[] mm=s2.toCharArray();
int[] next=getNext(mm);
int index1=0;
int index2=0;
while(index1<ss.length&&index2<mm.length){
if(ss[index1]==mm[index2]){
index1++;
index2++;
}else if(next[index2]==-1){
index1++;
}else{
index2=next[index2];
}
}
return index2!=mm.length?-1:index1-index2;
}
//求解next数组的过程
private static int[] getNext(char[] mm) {
if(mm.length==1){
return new int[]{0};
}
int[] next=new int[mm.length];
next[0]=-1;
next[1]=0;
int pos=2;//代表当前的字符创需要求解最长匹配前缀和后缀的位置
int cn=0;//记录前一个记录前缀未匹配的第一个位置
while(pos<mm.length){
if(mm[pos-1]==mm[cn]){
next[pos++]=++cn;
}else if(cn>0){
cn=next[cn];
}else{
next[pos++]=0;
}
}
return next;
}
}
KMP算法代码实现
最新推荐文章于 2023-07-30 14:40:47 发布