KMP入门题目[不定期更新]

HDU 1711 Number Sequence(模板题)

#include <cstdio>



const int MAXN = 1000010;

const int MAXL = 10010;



int N, M;



int textS[MAXN];

int tarS[MAXL];

int next[MAXL];



void GetNextVal( int* s, int* nextval, int len )

{

    int i = 0, j = -1;

    nextval[0] = -1;

    while ( i < len )

    {

        if ( j == -1 || s[i] == s[j] )

        {

            ++i, ++j;

            nextval[i] = j;

        }

        else j = nextval[j];

    }

    return;

}



int KMP( int *t, int lent, int *s, int lens )

{

    GetNextVal( t, next, lent );

    int i = 0, j = 0;

    while ( j < lens )

    {

        if ( i == -1 || s[j] == t[i] )

        {

            ++i, ++j;

            if ( i == lent ) return j;

        }

        else i = next[i];

    }

    return -1;

}



int main()

{

    int T;

    scanf( "%d", &T );

    while ( T-- )

    {

        scanf( "%d%d", &N, &M );

        for ( int i = 0; i < N; ++i ) scanf( "%d", &textS[i] );

        for ( int i = 0; i < M; ++i ) scanf( "%d", &tarS[i] );



        int ans = KMP( tarS, M, textS, N );

        if ( ans < 0 ) printf( "%d\n", ans );

        else printf("%d\n", ans - M + 1 );

    }

    return 0;

}
View Code

 HDU 1686 Oulipo(模板题)

#include <cstdio>

#include <cstring>

#include <cstdlib>



const int MAXN = 1000010;

const int MAXL = 10010;



char tarS[MAXL];

char testS[MAXN];

int next[MAXL];



void GetNextVal( char *s, int len, int *p )

{

    int i = 0, j = -1;

    p[0] = -1;

    while ( i < len )

    {

        if ( j == -1 || s[i] == s[j] )

        {

            ++i, ++j;

            p[i] = j;

        }

        else j = p[j];

    }

    return;

}



int KMP( char *t, char *s )

{

    int cnt = 0;

    int lent = strlen(t);

    int lens = strlen(s);

    GetNextVal( t, lent, next );



    int i = 0, j = 0;

    while ( j < lens )

    {

        if ( i == -1 || s[j] == t[i] )

        {

            ++i, ++j;

            if ( i == lent )

            {

                ++cnt;

                i = next[i];

            }

        }

        else i = next[i];

    }



    return cnt;

}



int main()

{

    int T;

    scanf( "%d", &T );

    while ( T-- )

    {

        scanf( "%s%s", tarS, testS );

        printf("%d\n", KMP( tarS, testS ) );

    }

    return 0;

}
View Code

 HDU 2203 亲和串

#include <cstdio>

#include <cstring>

#include <cstdlib>



const int MAXN = 100010;



char testS[ MAXN << 1 ];

char tarS[MAXN];

char temp[MAXN];

int next[MAXN];



void GetNextVal( char *s, int len, int *p )

{

    int i = 0, j = -1;

    p[0] = -1;

    while ( i < len )

    {

        if ( j == -1 || s[i] == s[j] )

        {

            ++i, ++j;

            p[i] = j;

        }

        else j = p[j];

    }

    return;

}



bool KMP( char *s, int lenS, char *t, int lenT )

{

    GetNextVal( t, lenT, next );

    int i = 0, j = 0;

    while ( j < lenS )

    {

        if ( i == -1 || s[j] == t[i] )

        {

            ++i, ++j;

            if ( i == lenT ) return true;

        }

        else i = next[i];

    }

    return false;

}



int main()

{

    while ( ~scanf( "%s", temp ) )

    {

        scanf("%s", tarS );

        int lenS = strlen(temp);

        int lenT = strlen(tarS);

        if ( lenT > lenS )

        {

            puts("no");

            continue;

        }



        strcpy( testS, temp );

        strcpy( &testS[lenS], temp );



        KMP( testS, lenS + lenS, tarS, lenT ) ? puts("yes") : puts("no");



    }

    return 0;

}
View Code

POJ 3450 Corporate Identity KMP+二分

二分串长,求出每个串长的所有子串,只要找到一个符合的子串即可。

#include <cstdio>

#include <cstring>

#include <cstdlib>

#include <algorithm>



using namespace std;



const int MAXN = 4010;

const int MAXL = 210;



int N;

char str[MAXN][MAXL];

char temp[MAXL];

char anser[MAXL];

int nextval[MAXL];

int len[MAXN];



void GetNextVal( char *s, int lenth )

{

    int i = 0, j = -1;

    nextval[0] = -1;

    while ( i < lenth )

    {

        if ( j == -1 || s[i] == s[j] )

        {

            ++i, ++j;

            if ( s[i] != s[j] ) nextval[i] = j;

            else nextval[i] = nextval[j];

        }

        else j = nextval[j];

    }

    return;

}



bool KMP( char *t, char *s, int lenth, int lenn )

{

    GetNextVal( t, lenth );

    int i = 0, j = 0;

    while ( j < lenn )

    {

        if ( i == -1 || s[j] == t[i] )

        {

            ++i, ++j;

            if ( i == lenth ) return true;

        }

        else i = nextval[i];

        //if ( i == lenth ) return true;

    }

    return false;

}



bool check( int tpL )

{

    bool flag = false;

    bool ok = false;

    for ( int st = 0; st + tpL - 1 < len[0]; ++st )

    {

        for ( int k = 0; k < tpL; ++k )

            temp[k] = str[0][ st + k ];

        temp[ tpL ] = '\0';

        //puts(temp);



        ok = true;

        for ( int i = 1; i < N; ++i )

            if ( !KMP( temp, str[i], tpL, len[i] ) )

            {

                ok = false;

                break;

            }

        if ( ok )

        {

            flag = true;

            if ( anser[0] == '\0' ||

                ( strlen(anser) == strlen(temp) && strcmp( anser, temp ) > 0 ) || ( strlen(anser) < strlen(temp) ) )

                strcpy( anser, temp );

        }

    }

    return flag;

}



int main()

{

    while ( scanf( "%d", &N ), N )

    {

        int bound = 1 << 30;

        for ( int i = 0; i < N; ++i )

        {

            scanf( "%s", str[i] );

            len[i] = strlen( str[i] );

            bound = min( bound, len[i] );

        }



        int low = 0;

        int high = bound;

        int mid, ans = 0;

        anser[0] = '\0';

        while ( low <= high )

        {

            mid = ( low + high ) >> 1;

            if ( check( mid ) )

            {

                ans = mid;

                low = mid + 1;

            }

            else high = mid - 1;

        }



        if ( !ans ) puts("IDENTITY LOST");

        else puts(anser);

    }

    return 0;

}
View Code

POJ 2752 Seek the Name, Seek the Fame

next函数的应用

#include <cstdio>

#include <cstring>

#include <cstdlib>



const int MAXN = 400010;



char str[MAXN];

int next[MAXN];

int ans[MAXN];

int len;



void getNext( char *s )

{

    int i = 0, j = -1;

    next[0] = -1;

    while ( i < len )

    {

        if ( j == -1 || s[i] == s[j] )

        {

            ++i, ++j;

            next[i] = j;

        }

        else j = next[j];

    }

    return;

}



int main()

{

    while ( ~scanf( "%s", str ) )

    {

        len = strlen(str);

        getNext( str );

        int cnt = 0;

        ans[0] = len;

        int i = len;

        while ( next[i] > 0 )

        {

            ans[ ++cnt ] = next[i];

            i = next[i];

        }

        for ( ; cnt >= 0; --cnt )

        {

            printf( "%d", ans[cnt] );

            if ( cnt ) putchar(' ');

        }

        puts("");

    }

    return 0;

}
View Code

 HDU 2087 剪花布条

求一个串在另一个串中的出现次数,KMP模板题

#include <cstdio>

#include <cstring>

#include <cstdlib>



const int MAXN = 1010;



char str[MAXN];

char tmp[MAXN];

int nextval[MAXN];

int cnt;



void getNextval(char *s, int *nextval, int length )

{

    int i=0,j=-1;

    nextval[0]=-1;

    while(i<length)

    {

        if(j==-1||s[i]==s[j])

        {

            ++i;

            ++j;

            //next[i]=j;

            if (s[i]!=s[j])

                nextval[i]=j;

            else

                nextval[i]=nextval[j];

        }

        else

            j=nextval[j];

    }

}



void KMP( char *t, char *s )   //s为主串,t为模式串

{

    int lenth = strlen(t);

    int len = strlen(s);

    getNextval( t, nextval, lenth );

    int i = 0, j = 0;

    while ( j < len )

    {

        if ( i == -1 || s[j] == t[i] )

        {

            ++i, ++j;

            if ( i == lenth )

            {

                ++cnt;

                i = 0;

            }

        }

        else i = nextval[i];

    }

    return;

}



int main()

{

    while ( scanf( "%s", str ) == 1 && str[0] != '#' )

    {

        scanf( "%s", tmp );

        cnt = 0;

        KMP( tmp, str );

        printf( "%d\n", cnt );

    }

    return 0;

}
View Code

 HDU 2594 Simpsons’ Hidden Talents (next函数应用)

把两个串连接起来,中间用一个没出现过的字符分隔开,直接输出最后一个字符的next的值。

#include <cstdio>

#include <cstring>

#include <cstdlib>



using namespace std;



const int MAXN = 50010;



char str[MAXN << 1];

char tmp[MAXN];

int nextval[MAXN << 1];

int length;



void getNext(char s[],int next[])

{

    length=strlen(s);

    int i=0,j=-1;

    next[0]=-1;

    while(i<length)

    {

        if(j==-1||s[i]==s[j])

        {

            ++i;

            ++j;

            next[i]=j;

        }

        else

            j=next[j];

    }

    return;

}



int main()

{

    while ( scanf( "%s%s", str, tmp ) == 2 )

    {

        int len = strlen(str);

        str[len] = '$';

        str[len + 1] = '\0';

        strcat( str, tmp );

        getNext( str, nextval );

        str[ nextval[length] ] = '\0';

        if ( nextval[length] > 0 )

        printf( "%s %d\n", str, nextval[length] );

        else puts("0");

    }

    return 0;

}
View Code

 URAL 1423. String Tale ( KMP模板题 )

#include <cstdio>

#include <cstring>

#include <cstdlib>



using namespace std;



const int MAXN = 250010;



int nextval[MAXN << 1];

char str[MAXN << 1];

char tmp1[MAXN];

char tmp2[MAXN];

int len;



void getNextval( char s[],int nextval[], int length )

{

    int i=0,j=-1;

    nextval[0]=-1;

    while(i<length)

    {

        if(j==-1||s[i]==s[j])

        {

            ++i;

            ++j;

            //next[i]=j;

            if (s[i]!=s[j])

                nextval[i]=j;

            else

                nextval[i]=nextval[j];

        }

        else

            j=nextval[j];

    }

}



int KMP( char *t, char *s )   //s为主串,t为模式串

{

    int lenth = strlen(t);

    int len = strlen(s);

    getNextval( t, nextval, lenth );

    int i = 0, j = 0;

    while ( j < len )

    {

        if ( i == -1 || s[j] == t[i] )

        {

            ++i, ++j;

            if ( i == lenth ) return j;

        }

        else i = nextval[i];

    }

    return -1;

}



int main()

{

    while ( scanf( "%d", &len ) == 1 )

    {

        scanf( "%s%s", tmp1, tmp2 );

        strcpy( str, tmp1 );

        strcat( str, tmp1 );

        int ans = KMP( tmp2, str );

        //printf( "ans = %d\n", ans );

        if ( ans == -1 ) puts("-1");

        else if ( ans == len ) puts("0");

        else printf( "%d\n", len + len - ans );

    }

    return 0;

}
View Code

 

你可能感兴趣的:(KMP)