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
", ans );
        else printf("%d
", 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
", 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 ] = '';
        //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] == '' ||
                ( 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] = '';
        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
", 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] = '';
        strcat( str, tmp );
        getNext( str, nextval );
        str[ nextval[length] ] = '';
        if ( nextval[length] > 0 )
        printf( "%s %d
", 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
", ans );
        if ( ans == -1 ) puts("-1");
        else if ( ans == len ) puts("0");
        else printf( "%d
", len + len - ans );
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/GBRgbr/p/3207396.html