KMP算法
思路
- 数组
next[i]
:表示位置为i
的后缀所能匹配的最长的前缀的长度。如:"ababa"中第4个位置的字符 'a' 所能匹配的最长前缀为 "aba",next = 3;"abcdab"中第5个字符 'b' 所能匹配的最长的前缀为 "ab",next为2。
实现
辅助数组
private static int[] generateNext(String str){
int len = str.length();
int[] next = new int[len];
for(int i = 2; i < len; i++)
{
int head = next[i-1];
while(head > 0 && str.charAt(head+1) != str.charAt(i))
head = next[head]; // 若无法延续前一个位置向后匹配,则跳转到前一个字符所匹配的位置继续向后匹配
if(str.charAt(head+1) == str.charAt(i)) //此时已找到前面字符的匹配长度,再检查当前字符与后一个字符是否相等
head++;
next[i] = head; // head 即为以i为结尾的匹配前缀的最长长度
}
return next;
}
计算匹配
public static boolean match(String str1, String str2){
str1 = '$'+str1;
str2 = '$'+str2;
int[] next = generateNext(str2);
int len1 = str1.length(), len2 = str2.length();
int head = 0;
for(int i = 1; i < len1; i++)
{
while(head > 0 && str2.charAt(head+1) != str1.charAt(i)) // 如果不匹配,则最长可以跳转到开始后的head字符处
head = next[head];
if(str2.charAt(head+1) == str1.charAt(i)) // 如果当前字符匹配,则向后匹配
head++;
if(head == len2-1) // 匹配成功,直接返回
return true;
}
return false;
}