char * BruteForce( char * pat, int m, char * text, int n )
{
for ( ; *text != '\0'; text++ )
if ( strncmp( pat, text, m ) == 0 ) // strncmp is O(m)
return text;
return 0;
}
int rehash(int d, int a, int b, int h)
{
return ((h - a*d) << 1) + b;
}
char * RabinKarp(char * pat, int m, char * text, int n)
{
int d, hPat, hText, i, j;
/* Preprocessing */
/* computes d = 2^(m-1) with the left-shift operator */
for (d = i = 1; i < m; ++i)
d <<= 1;
for (hText = hPat = i = 0; i < m; ++i)
{
hPat = (hPat<<1) + pat[i]; // compute hash of pattern
hText = (hText<<1) + text[i]; // compute initial hash of text
}
/* Searching */
j = 0;
while (j <= n-m)
{
if ( hPat == hText && memcmp(pat, text + j, m) == 0 )
return text + j;
hText = rehash(d, text[j], text[j + m], hText);
++j;
}
}
void preProcPat( char * pat, char * next )
{
int i = 0;
int j = -1;
next[0] = -1;
do {
if ( j == -1 || pat[i] == pat[j] )
{
i++;
j++;
next[i] = pat[j] == pat[i] ? next[j] : j;
}
else
j = next[j];
}
while ( pat[i] != '\0' );
}
char * KnuthMorrisPratt( char * pat, char * text )
{
int next[MAXPATLEN];
preProcPat( pat, next );
for ( int j=0; *text != '\0'; )
{
if ( j == -1 || pat[j] == *text )
{
text++;
j++;
if ( pat[j] == '\0' )
return text - j;
}
else
j = next[j];
}
return 0;
}
void preProcPat( char * pat, int skip[], int d[] )
{
int j, k, m, t, t1, q, q1;
int f[MAXPATLEN]; // auxiliary table
m = strlen( pat );
for( k=0; k<MAXCHAR; k++ )
skip[k] = m;
for( k=1; k<=m; k++ )
{
d[k-1] = (m << 1) - k;
skip[pat[k-1]] = m-k;
}
t = m + 1;
for( j=m; j > 0; j-- )
{
f[j-1] = t;
while( t <= m && pat[j-1] != pat[t-1] )
{
d[t-1] = min( d[t-1], m-j );
t = f[t-1];
}
t--;
}
q = t;
t = m + 1 - q;
q1 = 1;
t1 = 0;
for( j=1; j<=t; j++ )
{
f[j-1] = t1;
while( t1 >= 1 && pat[j-1] != pat[t1-1] )
t1 = f[t1-1];
t1++;
}
while( q < m )
{
for( k=q1; k<=q; k++ )
d[k-1] = min( d[k-1], m+q-k );
q1 = q + 1;
q = q + t - f[t-1];
t = f[t-1];
}
}
char * BoyerMoore( char * pat, int m, char * text, int n )
{
int j, k, m, skip[MAXCHAR], d[MAXPATLEN];
preProcPat( pat, skip, d );
for( k = m - 1; k < n; k += max(skip[text[k] & (MAXCHAR-1)], d[j]))
{
for( j=m-1; j >= 0 && text[k] == pat[j]; j--)
k--;
if( j == -1)
return text + k + 1;
}
return 0;
}