KMP算法【字符串搜索算法】
KMP算法
1. 算法核心
- 利用匹配失败后的信息
- 尽量减少模式串(B)与主串(A)的匹配次数
- 以达到快速匹配的目的
- 通过一个 next 数组,保存模式串(B)中 前后最长公共子序列的长度,每次回溯时,通过 next 数组找到,前面匹配过的位置,省去了大量的计算时间
2. 如何减少匹配次数
2.1. 字符串的前缀和后缀
比如字符串:ababacb
前缀集合 | 后缀集合 |
---|---|
2.2. 构建next数组
注意:当只有一个元素,它没有最长公共前后缀【next[0] = 0】
3. 代码实现
package com.kmp;
public class KMP {
static List<Integer> list = new ArrayList<>();
public static void main(String[] args) {
String s = "BBC ABCDAB ABCDABCDABDEdsafeABCDABD";
String target = "ABCDABD";
int[] next = kmpNext(target);
kmpSearch(s, target, next);
System.out.println(list);
}
public static List<Integer> kmpSearch(String s, String target, int[] next){ // 2个
int m = str2.length();
// 遍历
for (int i = 0, j = 0; i < str1.length(); i++) {
while (j > 0 && s.charAt(i) != target.charAt(j)){ // 如果不等了,就一直向前推进,找到上一个相等的位置
j = next[j - 1];
}
if (s.charAt(i) == target.charAt(j)){
j++;
}
if (j == m){
list.add(i - m + 1);
j = 0; // j 重置【匹配上了之后,j 重头开始匹配】
}
}
return list;
}
// 获得一个模式串的 next 数组
public static int[] kmpNext(String target) { // 单个
int[] next = new int[target.length()];
next[0] = 0;
for (int i = 1, j = 0; i < target.length(); i++) {
while (j > 0 && target.charAt(i) != target.charAt(j)){
j = next[j - 1];
}
if (target.charAt(i) == target.charAt(j)) {
next[i] = ++j;
}
}
return next;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix