HDU 4763 Theme Section ( KMP next函数应用 )

设串为str, 串长为len。

对整个串求一遍next函数,从串结尾开始顺着next函数往前找<=len/3的最长串,假设串长为ans,由于next的性质,所以找到的串肯定满足E……E这种形式,然后就是在str[ans]-str[len-2*ans]中查找是不是包含E,找到就输出,找不到就沿着next向下寻找,缩短串长。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>

using namespace std;

const int MAXN = 1000100;

char str[MAXN];
char tmp[MAXN];
int nextval[MAXN];
int len;

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;
}

int main()
{
    int T;
    scanf( "%d", &T );
    while ( T-- )
    {
        scanf( "%s", str );
        len = strlen(str);
        GetNextVal( str, len );
        int ans = nextval[len];
        while ( ans > len/3 ) ans = nextval[ans];
        while ( ans > 0 )
        {
            if ( KMP( str, &str[ans], ans, len - ans - ans ) )
                break;
            ans = nextval[ans];
        }
        if ( ans < 0 ) printf("%d\n", len/3);
        else printf( "%d\n", ans );
    }
    return 0;
}

 

posted @ 2013-09-29 09:18  冰鸮  阅读(284)  评论(0编辑  收藏  举报