I learned about the KMP algorithm in the data structure book .. In my opinion, compared with the ordinary BF algorithm, KMP avoids many unnecessary matches. The essence of KMP algorithm is the use of the next array... In short, the next array stores the "mismatch" between the J-character in the mode string and the corresponding character in the main string, in a mode string, you must repeat the position of the character that is not matched with the character in the main string... I think this sentence is a good summary...
Question 1:
HDU 1711 Number Sequence
Question link:
Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 1711
This question is to find that the pattern string is matched from the position in the main string... Directly set the template .. Code:
# Include <cstdio> # include <cstring> const int maxn = 1000000 + 10; int s [maxn], p [maxn]; int next [maxn]; int n, m; /* algorithm complexity: O (m + n) */void getnext () {Int J, K; next [0] =-1; j = 0; k =-1; /* n = strlen (p) */while (j <m) {If (k =-1 | P [J] = P [k]) // P [J] = P [k] {J ++; k ++; next [J] = K ;} else // P [J]! = P [k] K = next [k] ;}} int KMP () {int I, j; I = 0, j = 0; getnext (); while (I <n) {If (j =-1 | s [I] = P [J]) {I ++; j ++ ;} else J = next [J]; If (j = m) return I-m + 1;} return-1;} int main () {int T; scanf ("% d", & T); While (t --) {scanf ("% d", & N, & M); For (INT I = 0; I <n; I ++) scanf ("% d", & S [I]); For (INT I = 0; I <m; I ++) scanf ("% d", & P [I]); int ans = KMP (); printf ("% d \ n", ANS);} return 0 ;}
Question 2: poj 3461 oulipo question link: http://poj.org/problem? Id = 3461
This question uses the next array to determine how many times a mode string appears in the main string .. Template submission
# Include <cstdio> # include <cstring> # include <iostream> using namespace STD; const int maxn = 1000000 + 10; char s [maxn], p [maxn]; int next [maxn]; int n, m;/* The algorithm complexity is O (m + n) */void getnext () {Int J, K; next [1] = 0; j = 1; k = 0; while (j <= m) {If (k = 0 | P [J] = P [k]) // when a match occurs, P [J] = P [k] {J ++; k ++; next [J] = K;} else // P [J]! = P [k] K = next [k] ;}} int KMP () {int I, j; I = 1, j = 1; getnext (); while (I <n) {If (j = 0 | s [I] = P [J]) {I ++; j ++ ;} else J = next [J]; If (j = m + 1) return I-m;} return-1;} int kmp_count () {int ans = 0; int I, j = 1; if (n = 1 & M = 1) {If (s [1] = P [1]) return 1; else return 0;} getnext (); for (I = 1; I <= N; I ++) {While (j> 1 & S [I]! = P [J]) J = next [J]; If (s [I] = P [J]) J ++; If (j = m + 1) {ans ++; j = next [J] ;}} return ans ;}int main () {int t; scanf ("% d", & T ); while (t --) {scanf ("% s", p + 1); scanf ("% s", S + 1); M = strlen (p + 1 ); N = strlen (S + 1); int ans2 = kmp_count (); printf ("% d \ n", ans2);} return 0;}/* ababcabcacbabcacabcacabababcab */
Question 3: HDU 1358 peroid
Link: http://acm.hdu.edu.cn/showproblem.php? PID = 1, 1358
This is a typical next Array application .. Period... Locate the misaligned part from the past. If it is a cycle string, the misplaced department is a cycle section .. Then (I-1) % (I-next [I]) must be 0 .. In this way, the problem is solved perfectly .... Code:
<H2> <PRE name = "code" class = "CPP"> # include <cstdio> # include <cstring> const int maxn = 1000000 + 10; char s [maxn], P [maxn]; int next [maxn]; int m;/* algorithm complexity: O (m + n) */void getnext () {Int J, K; next [1] = 0; j = 1; k = 0; while (j <= m) {If (k = 0 | P [J] = P [k]) // when a match occurs, P [J] = P [k] {J ++; k ++; next [J] = K;} else // P [J]! = P [k] K = next [k] ;}} int KMP () {int I, j; I = 0, j = 0; getnext (); while (I <strlen (s) {If (j =-1 | s [I] = P [J]) {I ++; j ++ ;} else J = next [J]; If (j = strlen (p) return I-strlen (p);} return-1;} int main () {int CAS = 1; while (~ Scanf ("% d", & M), m) {scanf ("% s", p + 1); getnext (); printf ("Test Case # % d \ n", CAS ++); For (INT I = 2; I <= m + 1; I ++) {If (next [I]> 1 & (I-1) % (I-next [I]) = 0) printf ("% d \ n", I-1, (I-1)/(I-next [I]);} printf ("\ n");} return 0;}/* 7abcabcc */
Question 4: pojpoj 2406 power strings question link: http://poj.org/problem? Id = 2406
This question is to determine whether the string is a periodic string. If yes, the output cycle is used .. So keep up with the question .. You only need to judge the end... That is, whether N % (n + 1-next [n + 1]) = 0 is true or not... Code:
#include<cstdio>#include<cstring>const int maxn=1000000+10;char p[maxn];int next[maxn],n;void Getnext(){ int j,k; next[1]=0; k=0; j=1; while(j<=n) { if(k==0||p[k]==p[j]) { k++; j++; next[j]=k; } else k=next[k]; }}int main(){ int ans; while(~scanf("%s",p+1)) { if(strcmp(p+1,".")==0) return 0; ans=-1; n=strlen(p+1); Getnext(); if(n%(n+1-next[n+1])==0) ans=n/(n+1-next[n+1]); if(ans==-1) ans=1; printf("%d\n",ans); } return 0;}
I hope you can correct the mistakes... I will also add some questions later...