KMP算法
简介
KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。时间复杂度O(m+n)。
先来了解一下前缀与后缀的概念。”Happy”的前缀集合为{“H”, “Ha”, “Hap”, “Happ”},同理,”Happy”的后缀集合为{“appy”,”ppy”, “py”, “y”},注意的字符串本身既不是属于前缀集合也不属于后缀集合。
KMP算法中,最重要的是理解next[]数组是如何形成的。
next[]数组元素中的值为:字符串的前缀集合与后缀集合的交集中最长元素的长度。
举几个例子说明一下。
比如字符串”aba”,因为这个”aba”这个字符的前缀集合与后缀集合中,相等的并且最长的元素长度为1。
例如字符串”ababab”,计算一下该字符串的value。
前缀集合中存在字符串”abab”,后缀集合中也存在字符串”abab”,即该字符串的value为4。
在该字符串中,前缀集合中的最长元素为”ababa”,后缀集合中最长的元素为”babab”,显然这两个字符串是不相等的,所以该字符串的value为4。
剩下的以此类推。
为了编程的方便,我们把value的值向后移动一个位置,并设置第一个值为-1。
这里附上java代码:
public static void getNext(char[] p, int[] next)
{
next[0] = -1;
int i = 0, j = -1;
while (i < p.length - 1)
{
if (j == -1 || p[i] == p[j])
{
++i;
++j;
next[i] = j;
}
else
j = next[j];
}
}
求解好next[]数组后,第二步就需要依靠next[]数组,来进行串匹配。
public static int KMP(char[] t, char[] p, int[] next)
{
int i = 0;
int j = 0;
while (i < t.length && j < p.length )
{
if (j == -1 || t[i] == p[j])
{
i++;
j++;
}
else
j = next[j];
}
if (j == p.length)
return i - j;
else
return -1;
}
直接举例说明清晰一点。
在eclipse上运行一遍代码,测试结果。
public static void main(String[] args) {
// TODO Auto-generated method stub
String s = "abababca";
String g = "abc";
int[] next = new int[100];
KMP_Alogrithm.getNext(s.toCharArray(), next);
System.out.println(KMP_Alogrithm.KMP(s.toCharArray(), g.toCharArray(), next));
}
输出结果正确。
本文详细介绍KMP算法的工作原理及其实现过程,通过实例演示如何构建next数组并进行字符串匹配,适用于初学者掌握快速字符串匹配技巧。
10万+

被折叠的 条评论
为什么被折叠?



