KMP 演算法 詳解

來源:互聯網
上載者:User

 這個演算法簡單,但是這兩天做了兩個kmp的演算法,都沒做出來,細細的想想,我的kmp一直是我的一塊心病,一直沒有完全的理解,對於我來說,這個演算法真的很難!好吧,你也許會說這個演算法很簡單啊,next函數是個模板,套上之後匹配就是了,嗯,我同意,簡單,但是next函數是怎麼求的呢?得出的結果中有什麼重要訊息嗎?

我先在這兒存幾個網址,以後我再細細的看:http://www.ics.uci.edu/~eppstein/161/960227.html http://www.ics.uci.edu/~eppstein/161/960222.html

這裡面的東西全是英文的,聽說很不錯

開始kmp演算法,開始學的時候總是一頭的霧水,弄不明白,

其實next(j)的求法才是KMP演算法最關鍵的地方,要理解了它,才算是理解了KMP呀!我們來探索一下next(j)內部的原理。next(j)的值完全可以看成一個函數,它的自變數是模式串和失配位置j。 假設某一個模式串裡,next(6) = 3的話,這意味著什麼呢? 就是說如果第6個位置失配了,那麼我直接拿模式串第3個來和主串第6個比較,之所以能這麼比,只有可能是模式串的第1、2個和主串的第4、5個是匹配的,但是主串的4、5個和模式串的4、5個也是匹配的,由相等關係的傳遞性,我們得知模式串的1、2個和4、5個是匹配的。
如果模式串內部存在相同的片段,例如123和345相同這樣的情況,那麼我們就可以在後一個相同片段的結束出失配時,從前一個相同片段的結束處繼續比較。而如果不存在相同的片段,那麼就說明主串失配位置之前的部分不會再有匹配了(否則矛盾了),我們可以從主串失配位置的後一個位置繼續比較了。
這樣的一對相同片段恰好要從模式串的第一個開始,這樣給了我們便利,只需要:模式串第1個和第2個開始依次比較,
然後第1個和第3個開始依次比較,然後是第1個和第4個,依次類推,就能找到全部可能的相同片段了。湊巧,這也恰好是一個找尋模式串的任務,自己既是主串又是模式串。上述的自我比較過程中,在每一次比較相同時,我們都可以記下一個next值,而出現失配時,我們從主串的下個位置重新開始比,等等,想起什麼來了,對,主串不需要回溯。我們不是記下了前一個next值嗎?而如果第一次就不同呢,所以我們進行一個規定,next(1)=0,next(2)=1,這樣在第1個和第2個比較時,next(2)的值已經有了,隨後每一個比較都已經有了當前位置的next值了。這裡next值為0是表示失配位置前不可能有匹配了,這時主串從失配位置的後一個繼續比,而這個位置的next值我們同樣記為0。
明白了?好吧,看一個題:

Detection of Extraterrestrialp
Time Limit: 1000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu

[Submit]   [Go Back]   [Status]

Description


  Detection of Extraterrestrial 


E.T. Inc. employs Maryanna as alien signal researcher. To identify possible alien signals and background noise, she develops a method to evaluate the signals she has already received. The signal sent by E.T is more likely regularly alternative.

Received signals can be presented by a string of small latin letters 'a' to 'z' whose length isN. For each
X between 1 andN inclusive, she wants you to find out the maximum length of the substring which can be written as a concatenation ofX same strings. For
clarification, a substring is a consecutive part of the original string.

Input 

The first line contains T, the number of test cases (T200).
Most of the test cases are relatively small. T lines follow, each contains a string of only small latin letters 'a' - 'z', whose lengthN is less than 1000, without any
leading or trailing whitespaces.

Output 

For each test case, output a single line, which should begin with the case number counting from 1, followed byN integers. The
X-th (1-based) of them should be the maximum length of the substring which can be written as a concatenation ofX same strings. If that substring doesn't exist, output 0 instead. See the sample
for more format details.

Hint: For the second sample, the longest substring which can be written as a concatenation of 2 same strings is "noonnoon", "oonnoonn", "onnoonno", "nnoonnoo", any of those has length 8; the longest substring
which can be written as a concatenation of 3 same strings is the string itself. As a result, the second integer in the answer is 8 and the third integer in the answer is 12.

Sample Input 

2arisetocratnoonnoonnoon
Sample Output 

Case #1: 11 0 0 0 0 0 0 0 0 0 0Case #2: 12 8 12 0 0 0 0 0 0 0 0 0

Input

Output

Sample Input

Sample Output

Hint

[Submit]   [Go Back]   [Status]

 

以下代碼出處http://blog.csdn.net/allenjy123/article/details/6629885

/*KMP*//*注意:對ans[1]特殊考慮*//*AC代碼:288ms*/#include <iostream>#include <cstdio>#include <memory.h>#include <algorithm>#include <cstring>#define MAXN 1005#define max(a,b) (a>b?a:b)using namespace std;int cas,len;int ans[MAXN],next[MAXN];char s[MAXN];void get_next(char s[]){int i=1,t,lens=strlen(s+1);next[0]=-1;while(i<=lens){t=next[i-1];while((t+1)&&s[t+1]!=s[i])t=next[t];next[i]=t+1;i++;}}void Solve(){int i,j,k;memset(ans,0,sizeof(ans));ans[1]=len;char temp[MAXN];for(i=0;i<len;i++){strcpy(temp+1,s+i);get_next(temp);int len=strlen(temp+1);for(j=len;j>=1;j--){int x=j-next[j];if(j%x==0){int w=j/x;for(k=w;k>=1;k--)//注意這裡要更新多組答案ans[k]=max(ans[k],j-(w%k)*x);}}}}int main(){int i,T;cas=1;scanf("%d",&T);while(T--){scanf("%s",s);len=strlen(s);Solve();printf("Case #%d:",cas++);for(i=1;i<=len;i++)printf(" %d",ans[i]);printf("\n");}return 0;}/*asasasaCase #27: 7 4 6 0 0 0 0*/

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.