KMP字串匹配演算法 Z

2021-09-30 06:54:58 字數 2190 閱讀 5466

最普通的字串匹配演算法就不記了,簡單貼一下**

int strstr

(char *sub,

char * str

) }if

( * ( q+i

) ==

'/0 ')

return p-str;

return

-1 ;

} 下面說說我理解的kmp演算法,與普通匹配演算法不一樣的是,kmp演算法在子串匹配失效的時候,下一步並不是重新從子串的頭部開始匹配,而是根據一下next函式計算出下一步應該從子串的什麼部位開始匹配。舉個例子更容易說明

紅色為失效位置, '^'表示的當前是指標位置,'~'表示此次匹配a串開始的位置。

若是普通的匹配演算法,當失效時,c串指標要回溯到頭部,a串指標也要回溯到'~'的下一位。也就是下一步應該是從a的第二字元(e.g. 'b')和c的開頭(e.g. 'a')開始匹配。如此迴圈

直到找到a串中的某乙個位置可以匹配c串。

然而從上面的匹配過程中,可以發現a和b的藍色部分是第一步中已經確認匹配過的,上面四步的匹配其實可以看作是藍色部分的前半段與後半段在進行比較,而且前三步在藍色部分就已經匹配失效了,所以這些比較是無謂的,因為它與父串a無關的,是屬於子串c本身的資訊。只有第四步才涉及了與父串a中的字元 ('c')的比較

kmp演算法正是利用這一點,它事先利用子串本身的資訊就計算出當某一次匹配失效時,下一次應該繼續匹配的位置。也就是當c串在最後乙個'b '匹配失效時,它省略了前三步(1,2,3)無謂的匹配,下一步比較將在'd'與'c'之間進行。這樣父串a無需回溯,c串用乙個next函式決定它將回溯的位置。所以next函式至關重要,也是這個演算法的關鍵。

從上面的分析可以知道next函式是子串c本身的性質決定的

假設子串

next(j)=k(k>=0): 當p的第 j+1個字元

當next(j)=-1時,子串指標回溯到頭,父串指標前進一步;

在設計計算next值的程式的時候,我們沒有必要每一步都去計算maximum(k),可以用遞迴方式來做

舉個例子

假設子串為p:"abacabab ", 且我們將要求的是'b '的next值, e.g. next[7]

假設next[0~6]均為已知: next[0]=-1, next[1]=-1 , next[2]=0 , next[3]=-1 , next[4]=0 , next[5]=1 ,next[6]=2

"aba

caba

b"next[6]=2可以說明p[0~2](藍)與p[4~6](紅)是一樣的

要求next[7]的值,我們可以找前6位("abacaba")中最長的前半段與後半段相等的子串,然後比較前半段子串的下一位是否和p[7]相等。在這個例子中, p[0~next[6]](e.g. p[0~2])就是這樣的子串,接下來我們比較 c 和 b也就是p[next[6]+1]('c')和p[7]('b').

在上的例子中 p[next[6]+1]=p[3]('c') ,與p[7]('b')不相等, 但是  p[next[next[6]]+1] = p[next[2]+1] = p[1]('b'), 與p[7]('b')相等

最後可以得到next[7] = next[next[6]]+1 = next[2]+1= 1;

計算next值的**:

void calnext

(char * p,

int next)if

( p [ k

+1] ==p

[ i]

)//如果相等而結束, 則找到一對長度為k的字首字串和字尾字串

next

[ i] = k

+1 ;      

//增加了乙個相同項

else

next

[ i] =

-1 ;         

//其他情況 }

} 匹配的**:

int find

(char *t,

char * pat

)else }

if( * ( q+i

) ==

'/0 ')

return p-t-n;

else

return

-1 ;

} 記錄一下自己理解的kmp以免以後自己都忘記當時怎麼理解的。

KMP演算法 字串匹配

kmp演算法基本思想 我們在用常規的思想做 字串匹配時候是 如 對如 字元如果 t abab 用p ba 去匹配,常規思路是 看 t 第乙個元素 a 是否 和p 的乙個 b 匹配 匹配的話 檢視各自的第二個元素,不匹配 則將 t 串的 第二個元素開始 和 p 的第乙個匹配,如此 一步一步 的後移 來...

KMP字串匹配演算法

kmp核心思想 計算模式串的next陣列,主串的索引在比較的過程中不回朔 ifndef kmp h define kmp h class kmp endif include kmp.h include include include using namespace std int kmp calcu...

KMP字串匹配演算法

在介紹kmp演算法之前,先介紹一下bf演算法。一.bf演算法 bf演算法是普通的模式匹配演算法,bf演算法的思想就是將目標串s的第乙個字元與模式串p的第乙個字元進行匹配,若相等,則繼續比較s的第二個字元和p的第二個字元 若不相等,則比較s的第二個字元和p的第乙個字元,依次比較下去,直到得出最後的匹配...