package algorithm.algorithm.kmp;
import java.util.Arrays;
/**
* @author AIMX_INFO
* @version 1.0
*/
public class KMPAlgorithm {
public static void main(String[] args) {
String str1 = "BBC ABCDAB ABCDABCDABDE";
String str2 = "ABCDABD";
int[] next = kmpNext(str2);
System.out.println(Arrays.toString(next));
int index = KMPSearch(str1, str2, next);
System.out.println("index = " + index);
}
//实现KMP搜索算法
/**
*
* @param str1 原始字符串
* @param str2 子串
* @param next 部分匹配表
* @return 返回搜索的结果
*/
public static int KMPSearch(String str1, String str2, int[] next){
//遍历初始字符串插找子串
for (int i = 0, j = 0; i < str1.length(); i++) {
//匹配某几位后如果后一位不再匹配,则重置 j
while (j > 0 && str1.charAt(i) != str2.charAt(j)){
j = next[j - 1];
}
//判断当前长串的某一位是否匹配子串,如果匹配,继续判断下一位
if (str1.charAt(i) == str2.charAt(j)){
j++;
}
//对比结束后,如果子串的长度等于 j的大小,则说明匹配成功
if (j == str2.length()){
return i - j + 1;
}
}
return -1;
}
//编写方法实现子串的部分匹配表
/**
* @param str 要获取的部分匹配表的子串
* @return 返回部分匹配表
*/
public static int[] kmpNext(String str) {
//创建数组模拟部分匹配表
int[] next = new int[str.length()];
//单个字符的匹配值始终为0
next[0] = 0;
//i为遍历这个子串的索引, j为遍历到的字符和前边重复字符串的长度
for (int i = 1, j = 0; i < str.length(); i++) {
//如果有重复子串,当下一位不重复后,重置 j
while (j > 0 && str.charAt(i) != str.charAt(j)){
j = next[j - 1];
}
//如果遍历到的字符和前边的字符重复,则j++,判断下一位是否重复
if (str.charAt(i) == str.charAt(j)){
j++;
}
//将重复的值存储到部分匹配表
next[i] = j;
}
return next;
}
}
原文:https://www.cnblogs.com/mx-info/p/14888146.html