KPM算法,是数据结构课本中串的模式匹配部分讲解的算法。它的需求是求解给定字符串是否包含指定的字符串。
【题目描述】
给定一个主串S及一个模式串P,判断模式串是否为主串的子串;若是,返回匹配的第一个元素的位置(序号从1开始),否则返回0;如S=“abcd”,P=“bcd”,则返回2;S=“abcd”,P=“acb”,返回0。
【思路】
KPM优化算法的关键在于部分匹配表的求解,部分匹配的实质就是,有时候,字符串头部和尾部会有重复的部分。例如,"ABCDAB"字符串中有两个"AB",那么它的部分匹配值就是2。搜索词移动的时候。只要将第1个"AB"已到第2个"AB"的位置就可以了。
字符串"abababca"的部分匹配表
char: | a | b | a | b | a | b | c | a |
index: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
value: | 0 | 0 | 1 | 2 | 3 | 4 | 0 | 1 |
数组 next 的提取代码:
void Getnext(int next[],String t)
{
int j=0,k=-1;
next[0]=-1;
while(j<t.length-1)
{
if(k == -1 || t[j] == t[k])
{
j++;k++;
next[j] = k;
}
else k = next[k];
}
}
【解法】
int KMP(String s,String t)
{
int next[MaxSize],i=0;j=0;
Getnext(t,next);
while(i<s.length&&j<t.length)
{
if(j==-1 || s[i]==t[j])
{
i++;
j++;
}
else j=next[j]; //j回退
}
if(j>=t.length)
return (i-t.length); //匹配成功,返回子串的位置
else
return (-1); //没找到
}
相关链接:
http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html