int KMP(String T, String P) { f() = KMP_failure_function(P); i = 0; j = 0; n = T.length(); m = P.length(); while ( i < n ) { if ( P[j] == T[i] ) { /* ------------------------ Check if we found P ------------------------ */ if ( j == (m-1) ) { return( i - (m-1) ); // Found P in T ! } /* ------------------------ Not yet, keep going... ------------------------ */ i++; j++; } else { /* --------------------------- Fail to match at P[j] ---------------------------- */ if ( j == 0 ) { /* ------------------------------------------------- First character in P ==> try next character in T ------------------------------------------------- */ i++; } else { /* ----------------------------------------------------- There is a prefix matched ==> go to the max matching suffix of the prefix ----------------------------------------------------- */ j = f(j-1); } } } return(-1); // No match found... } |
0123456789012345678901234567801 (ruler) i | v T: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx P: yyyyyyy ^ | j 0123456 (ruler) |
0123456789012345678901234567801 (ruler) i | v T: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx P: yyyyyyy ^ ^ | | | j 0123456 (ruler) | k = i - j |
while ( i < n ) { if ( P[j] == T[i] ) { /* ------------------------ Check if we found P ------------------------ */ if ( j == (m-1) ) { return( i - (m-1) ); // Found P in T ! } /* ------------------------ Not yet, keep going... ------------------------ */ i++; ********** j++; ********** } else { /* --------------------------- Fail to match at P[j] ---------------------------- */ if ( j == 0 ) { /* ------------------------------------------------- First character in P ==> try next character in T ------------------------------------------------- */ i++; ********** } else { /* ----------------------------------------------------- There is a prefix matched ==> go to the max matching suffix of the prefix ----------------------------------------------------- */ j = f(j-1); ********** } } } |
|
Summary:
|
Behold:
0123456789012345678901234567801 (ruler) i | v T: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx P: yyyyyyy ^ ^ | | | j 0123456 (ruler) | k = i - j <------------------------------> range(i) = n characters in T range(k) = n characters in T |
|
# time while loop can be executed ≤ 2 × n |
(Otherwise, we will increase one of the variable i or k by more than n !!!)
|
int KMP_failure_function(String P) { int i, j, m; int f[] = new int[P.length() + 1]; m = P.length(); f[0] = 0; // See KMP alg. for explanation (click here) i = 1; // Next value of f[] to compute j = 0; /* --------------------------------------- We are at this situation: p1 (i=1) p0 p1 .... pm-1 (j=0) --------------------------------------- */ while ( i < m ) { if ( P[j] == P[i] ) { /* ------------------------ Case 1: ------------------------ */ f[i] = j; // ******* Case 1 /* ------------------------ Next position... ------------------------ */ i++; j++; } else { /* --------------------------- Case 2: does not match ---------------------------- */ if ( j == 0 ) { /* ------------------------------------------------- No match possible ------------------------------------------------- */ f[i] = 0; // ********* i++; } else { /* ----------------------------------------------------- There is a prefix matched ==> go to the max matching suffix of the prefix and CONTINUE the search ----------------------------------------------------- */ j = f(j-1); // Jump and continue search... } } } } |
# time while loop can be executed ≤ 2 × m |
(Otherwise, we will increase one of the variable i or k by more than n !!!)
|
|