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