首页 > 代码库 > hdu1867(kmp)

hdu1867(kmp)

今天估计一直要刷kmp,kmp,kmp,kmp....

这题目非常容易理解,就是A+B问题,不同的是,要找到A串后缀与B串前缀的最长串。

比如 ABC+BC -> ABC  , ABC+BCD =ABCD   ,ABCD+ BC=ABCDBC

用的就是kmp啦,输入两个串 str1 str2 ,以str1模式串,str2为文本匹配,以str2为模式串,str1为文本串,分别匹配出最长的长度。再比较。

/***********************************************************
	> OS     : Linux 3.13.0-24-generic (Mint-17)
	> Author : yaolong
	> Mail   : dengyaolong@yeah.net
	> Time   : 2014年09月24日 星期三 15时31分51秒
 **********************************************************/
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
int next[123456];
void build_next ( char p[], char T[], int m )
{
    next[1] = 0;
    int k = 0;
    for ( int q = 2; q <= m; q++ )
    {
        while ( k > 0 && p[k + 1] != p[q] )
        {
            k = next[k];
        }
        if ( p[k + 1] == p[q] )
        {
            k = k + 1;
        }
        next[q] = k;
    }
}
int kmp ( char p[], char T[], int m, int n )
{
    build_next ( p, T, m );
    int q = 0;
    int res = 0;
    int i = 1;
    for ( ; i <= n; i++ )
    {
        while ( q > 0 && p[q + 1] != T[i] )
        {
            q = next[q];
        }
        if ( p[q + 1] == T[i] )
        {
            q = q + 1;
        }
    }
    if ( i <= n + 1 || ( i == n + 1 && q == m + 1 ) )
        return q;
    return 1;
}
int main()
{
    char p[123456];
    char T[123456];
    int C;
    p[0] = T[0] = '1';
    while ( scanf ( "%s", T + 1 ) != EOF )
    {
        scanf ( "%s", p + 1 );
        int x = kmp ( T, p , strlen ( T ) - 1, strlen ( p ) - 1 ) ;
        int y = kmp ( p, T, strlen ( p ) - 1 , strlen ( T ) - 1 ) ;
        if ( x > y || ( x == y && strcmp ( T, p ) > 0 ) )
        {
            cout << ( p + 1 );
            cout << ( T + x + 1 );
        }
        else
        {
            cout << ( T + 1 );
            cout << ( p + y + 1 );
        }
        cout << endl;
    }
    return 0;
}


hdu1867(kmp)