faraway  
 

下面是自己写的一个KMP算法实现。P为待查找串,Q为模式串,B为预处理数组。

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define MATCH_DETAIL 1

#if MATCH_DETAIL
void print_strP( char* P, int num )
{
    
int i;

    printf(
"\nP:%d\t", num - 1);
    
for ( i = 0; i < num; i++ )
        printf(
"%3c", P[i]);
    printf(
"\n");
}


void print_strQ( char* Q, int num, int indent )
{
    
int i;

    printf(
"\nQ:%d\t", num - 1);
    
/*    keep indent    */
    
for ( i = 0; i < indent; i++ )
        printf(
"%3c"' ');
    
for ( i = 0; i < num; i++ )
        printf(
"%3c", Q[i]);
    printf(
"\n");
}


void print_arrB( int* B, int num, int indent )
{
    
int i;

    printf(
"B:%d\t", num - 1);
    
/*    keep indent    */
    
for ( i = 0; i < indent; i++ )
        printf(
"%3c"' ');
    
for ( i = 0; i < num; i++ )
        printf(
"%3d", B[i]);
    printf(
"\n\n");
}


void show_status( char* P, char* Q, int* B, int s, int t)
{
    
if ( P == NULL || Q == NULL || B == NULL )
        
return;

    printf(
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
    print_strP( P, s 
+ 1 );
    print_strQ( Q, t 
+ 1, s - t );
    print_arrB( B, t 
+ 1, s - t );
}

#endif

void preprocess( char* Q, int* B )
{
    
int i;
    
int j;

    
if ( Q == NULL || B == NULL )
        
return;

    i 
= 1;
    j 
= 0;
    B[
0= 0;
    
while ( Q[i] != '\0' ) {
        
while ( j > 0 && Q[j] != Q[i] ) {
            j 
= B[j - 1];
        }

        
        
if ( Q[j] == Q[i] )
            j
++;
        
        B[i] 
= j;
        i
++;
    }


#if MATCH_DETAIL
    printf(
"preprocess string Q\n");
    print_strQ( Q, strlen(Q), 
0 );
    print_arrB( B, strlen(Q), 
0 );
#endif
}


void KMP( char* P, char* Q )
{
    
int i;
    
int j;
    
int *B;

    
if ( P == NULL || Q == NULL )
        
return;

    B 
= (int *)malloc( strlen(Q) );
    
if ( B == NULL ) return;

    preprocess(Q, B);

    i 
= j = 0;
    
while ( P[i] != '\0' ) {
        
/* if Q[j] cannot match P[i], change j to proper value and stop at zero */
        
while ( j > 0 && Q[j] != P[i] ) {
#if MATCH_DETAIL
            show_status( P, Q, B, i, j );
#endif
            j 
= B[j - 1];
        }

        
        
/*    current characters are matched, increase j    */
        
if ( Q[j] == P[i] )
            j
++;
#if MATCH_DETAIL
        
else
            show_status( P, Q, B, i, j );
#endif
        i
++;

        
if ( Q[j] == '\0' ) {
#if MATCH_DETAIL
            show_status( P, Q, B, i 
- 1, j - 1 );
#endif
            printf(
"Pattern matches at shift %d\n", i - j);
            
// find next pattern string
            j = 0;
        }

    }

}


int main( void )
{
    
char* P = "ababcabdbabcabcda";
    
char* Q = "abcabcd";

#if MATCH_DETAIL
    printf(
"string P:\n");
    print_strP( P, strlen(P) );
    printf(
"string Q:\n");
    print_strQ( Q, strlen(Q), 
0 );
#endif

    KMP( P, Q );

    
return 0;
}

posted on 2008-07-20 21:42  faraway  阅读(455)  评论(0编辑  收藏  举报