KMP算法--解決字符串匹配問題--模式串是否在文本串出現過
*利用之前判斷過的信息,通過next數組保存最長公共子序列的長度
*搜索詞/模式串 移動的位數=已匹配的字符數-對應的部分匹配值
在韓的例子里ABCDABD 初次匹配匹配了ABCDAB 6位,對應2,所以移動6-2=4位
e.g.
文本串 aabaabaaf
模式串 aabaaf
模式串的前綴:
a
aa
aab
aaba
aabaa
模式串的后綴:
f
af
aaf
baaf
abaaf
最長公共子序列的長度:
a 0
aa 1 (a和a)
aab 0
aaba 1 (a和a)
aabaa 2 (a和a,aa和aa)
aabaaf 0
前綴表:010120
從索引為2的位置開始繼續匹配
package LeetcodeExercise;
import java.util.Arrays;
/**
* @author: JESSICA
* @description: TODO
* @date: 2023/8/30 16:52
* @version: 1.0
*/
public class KMP {
public static void main(String[] args) {
String text_string = "BBC ABCDAB ABCDABCDABDE";
String pattern_string = "ABCDABD";
int[] next = kmpNext(pattern_string);
System.out.println(Arrays.toString(next));
int index = kmpSearch(text_string, pattern_string, next);
System.out.println(index);
}
//獲取一個字符串的部分匹配值表
public static int[] kmpNext(String dest){
int[] next = new int[dest.length()];
next[0] = 0;
for (int i = 1, j = 0; i < dest.length(); i++){
//找前后綴的相同的字符 當不相等時,令j向前一位 取next[j-1] 從這里更新j
while(j > 0 && dest.charAt(i) != dest.charAt(j)){
j = next[j-1];
}
//找前后綴的相同的字符 當相等時,j++,即部分匹配值+1
if(dest.charAt(i) == dest.charAt(j)){
j++;
}
next[i] = j;
}
return next;
}
public static int kmpSearch(String text_string, String pattern_string, int[] next){
for(int i = 0, j = 0; i < text_string.length(); i++){
//不匹配時,j需要重定向--kmp核心
while (j > 0 && text_string.charAt(i) != pattern_string.charAt(j)){
j = next[j-1];
}
if(text_string.charAt(i) == pattern_string.charAt(j)){
j++;//相同,繼續向后查找
}
//j就是在模式串定位 長度一樣相當于每一個字符都匹配了
if(j == pattern_string.length()){
return i-j+1;
}
}
return -1;
}
}
浙公網安備 33010602011771號