KMP算法
package demo2;
public class P83 {
//KMP算法
//思路:减少回退。
//主串s,模式串p;指针i、j分别指向s、p来比较。
//假设有两个模式串,p1在j失配,说明前面0~(j-1)与s相同,这段中p1的后缀与p2的前缀重合部分免检(这部分p2等于p1等于s)。
//易得,公共前后缀与s无关,可以由p本身得到。算出跳转位置构成next数组,j=next[j],后一个j为失配位置
public static void main(String[] args) {
String s="babaabbabc";
String p="babc";
System.out.println(kmp(s, p));
}
static int[] next(String p) {
int pLen=p.length();
int[] next=new int[pLen];
char[] pArr=p.toCharArray();
next[0]=-1; //-1是为了处理这一要i++的特殊情况
if(pLen==1)
return next;
next[1]=0;
int j=1; //递推法,求之后的next[]
//原理:next[j]等于k,就是j处失配后有k长度的公共前后缀。
int k=next[j];
while(j<pLen-1) {
//若j、k的字符相同,则(j+1)处失配的公共前后缀为k+1
if(k<0 || pArr[j]==pArr[k]) {
next[++j]=++k;
}
//若不同,则next[j]的值k不可用,继续找相同字符
else {
k=next[k];
}
}
return next;
}
static int kmp(String s,String p) {
int[] next=next(p);
int i=0;
int j=0;
int sLen=s.length();
int pLen=p.length();
while(i<sLen) {
if(j==-1 || s.charAt(i)==p.charAt(j)) {
i++;
j++;
}
else {
j=next[j];
}
if(j==pLen) { //匹配成功,此时i、j在结尾的再后一位
return i-pLen;
}
}
return -1; //找不到
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?