KMP算法是在給定的字符串中查找某一特定的字符串(我們稱之為模式串(Pattern)).
時間復雜度是O(m+n):m是模式串的字符數,n是給定的目標串的長度。
在寫自己見解之前,先給大家一個Martrix67大牛的關于KMP算法的一個鏈接
http://www.matrix67.com/blog/archives/115
我認為KMP算法的難點在于當匹配失效時,我們要將模式串的第幾個字符與當前目標串的失效處進行比較。
我們用T來表示目標串,P(m)來表示有m個字符的模式串。
已知P[1...q] 與 T[s+1,s+2,....s+q]匹配。而P[q+1] 不等于T[s+q+1];
那么T[s+q+1]應該和P的哪個字符進行比較呢?
由P[1..q] = T[s+1,...s+q]對應相等,假設T[s+q+1]要和P[k+1]進行比較(我們是基于1的字符串,即第一個字符我們用1而不是0來表示它的下標。)
那么我們必須保證
P[1...k] = T[ s+q-k+1...,s+q].
因為在一定之前P[1...q] = T[s+1,...s+q];所以P[q-k+1...q] = T[s+q-k+1,...,s+q];
P[q-k+1,...,q]是P從q之前的k個字符,即P[q]的后面k字符。
P[1...k]是P的前k個字符。
所以當我們在P[q+1]和T[s+q+1]不匹配時,
我們就是找到最大的k,使得前k個字符和后k個字符相等。
代碼如下:

long IndexOfSubString(LPCTSTR source,unsigned int start,LPCTSTR subStr)


{
long sourceLen = _tcslen(source);
long subLen = _tcslen(subStr);
long *helpArr = new long[subLen];
memset(helpArr,0,sizeof(long)*subLen);
helpArr[0] =-1;

long index(0);
long j(-1);
for(index=1;index<subLen;index++)

{
while(j>0 && subStr[index] !=subStr[j+1]) j = helpArr[j];

if(subStr[index] == subStr[j+1])
j++;

helpArr[index] = j;
}

j=-1;
for(index=start;index<sourceLen;index++)

{
while(j>-1&&source[index] !=subStr[j+1]) j=helpArr[j];

if(source[index] == subStr[j+1])
j++;
if(j==subLen-1)
return index-j;
}
delete[] helpArr;
return -1;
}