KMP演算法筆記

來源:互聯網
上載者:User

 

KMP演算法筆記關於KMP

(1)   
引子:

對於2個字串A,B,其中A為主串,B為待匹配的子串,如

i   1
2 3 4 5 6 7 8 ...

A:a b a a c c a b a b a
a b c a c b a c a c ...

B:a b a a b c a c

j   1
2 3 4 5 6 7 8 ...

當A[5] != B[5]時,蠻力法是從頭再來,而KMP演算法則不同,它採用一定的策略,調整j的位置,使得B[j] == A[i]。

(2)   
KMP主代碼:

int KMPSearch(const char * main_str, const char * sub_str, int * next)<br />{<br /> int i=0;<br /> int j=0;<br /> int main_len=strlen(main_str);<br /> int sub_len=strlen(sub_str);</p><p> while((i<main_len)&&(j<sub_len))<br /> {<br /> if(j == -1 || main_str[i] == sub_str[j]) {<br /> j++;<br /> i++;<br /> }else{<br /> j=next[j];<br /> }<br /> }</p><p> if(j == sub_len){<br /> return i-sub_len;<br /> }else{<br /> return -1;<br /> }<br />}

(3)從(2)中的代碼可以看出,KMP演算法的關鍵是構造next表。

關於next

1 next[i]表示的是:

在第i個字元前面的i-1個字元裡面,

從開頭開始的1個字元與最後1個字元是否相等,若不是,則next[i]=0,否則繼續看下面;

從開頭開始的2個字元與最後2個字元是否相等,若不是,則next[i]=1,否則繼續看下面;

從開頭開始的3個字元與最後3個字元是否相等,若不是,則next[i]=2,否則繼續看下面;

……

 

2 next數組求解思路:

第1位的next值為-1,第2位的next值為0,後面求解每一位的next值時,根

據前一位進行比較。

比較策略如下:

(1)   
將前一位與其(next值對應的字元)進行比較;

(2)   
如果相等,則該位的next值就是前一位的next值加上1;

(3)   
如果不等,向前繼續尋找(next值對應的字元)來與前一位進行比較;

(4)   
如果最後找到,則在這個位對應的值加上1,即為所求的next值;

(5)   
如果最後沒有找到,那麼所求next值為0。

 

3 next函數如下:

void CalculateNext(const char * sub_str, int len, char * next)<br />{<br /> int i=-1;<br /> int j=0;<br /> next[0]=-1;</p><p> while(j<len){<br /> //i == -1表示找到最後,策略(5)<br /> //sub_str[i] == sub_str[j]表示找到,策略(1)(2)<br /> if(i == -1 || sub_str[i] == sub_str[j]){<br /> //策略(2)(4)<br /> i++;<br /> j++;<br /> next[j]=i;<br /> }else{<br /> //策略(3)<br /> i=next[i];<br /> }<br /> }<br />}

KMP與DFA

附:

void CalculateNext(const char * sub_str, int len, int * next)<br />{<br />int i=-1;<br />int j=0;<br />next[0]=-1;<br />while(j<len){<br />if(i == -1 || sub_str[i] == sub_str[j]){<br />i++;<br />j++;<br />next[j]=i;<br />}else{<br />i=next[i];<br />}<br />}<br />}<br />int KMPSearch(const char * main_str, const char * sub_str)<br />{<br />int i=0;<br />int j=0;<br />int * next;<br />int main_len=strlen(main_str);<br />int sub_len=strlen(sub_str); </p><p>next = (int*)malloc(sizeof(int)*sub_len + 1);<br />CalculateNext(sub_str, sub_len, next);<br />while((i<main_len)&&(j<sub_len))<br />{<br />if(j == -1 || main_str[i] == sub_str[j]) {<br />j++;<br />i++;<br />}else{<br />j=next[j];<br />}<br />}<br />if(j == sub_len){<br />return i-sub_len;<br />}else{<br />return -1;<br />}<br />}<br />

 

 

 


 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.