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)
|
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 !!!)
|
|