hdu 1841 Find the Shortest Common Superstring

Find the Shortest Common Superstring

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 1222    Accepted Submission(s): 320


Problem Description
The shortest common superstring of 2 strings S1 and S2 is a string S with the minimum number of characters which contains both S1 and S2 as a sequence of consecutive characters. For instance, the shortest common superstring of “alba” and “bacau” is “albacau”.
Given two strings composed of lowercase English characters, find the length of their shortest common superstring. 
 
Input
The first line of input contains an integer number T, representing the number of test cases to follow. Each test case consists of 2 lines. The first of these lines contains the string S1 and the second line contains the string S2. Both of these strings contain at least 1 and at most 1.000.000 characters.
 
Output
For each of the T test cases, in the order given in the input, print one line containing the length of the shortest common superstring.
 
Sample Input
2 alba bacau resita mures
 
Sample Output
7 8
 这题很有趣,用kmp进行求解,主要考虑2种情况,对于2个串,s,t,如果是s串的最长前缀等于t串的后缀,那么我们就以s串为匹配串,t串为模式串,进行匹配。
反之亦然。具体实现看代码。
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
#define N 1000005
char  s[N],t[N];
int next[N];
void get_next(char b[])
{
     next[0]=-1;
     int i=0;
     int j=-1;
     int str=strlen(b);
     while(i<str-1)
     {
          if(j==-1||b[i]==b[j])
               next[++i]=++j;
          else
               j=next[j];
     }
}
int kmp(char a[],char b[],int stra,int strb)
{
     int i=0;
     int j=-1;
     get_next(b);
     while(i<stra&&j<strb)
     {
          if(j==-1||a[i]==b[j])
               i++,j++;
          else
               j=next[j];
     }
     return j;
     /*这里为什么返回的是j的值呢,想一想,假如我们是以s串为模式串进行匹配,
     我们要找的就是那个t的前缀等于s的后缀的最长的长度,还是拿样例说一下吧
     s:alba t:bacau 对于kmp算法,当s[i]==t[j]得时候j是加一的看样例,当t[0]==s[2]=b时
     j=1,继续往后走,t[1]==s[3]=a,j=2这时s串已经循环结束了,
     返回的j的值就是他们前缀与后缀相等的最长的长度了*/
}
int main()
{
     int i,j,n,ans,cnt,ls,lt;
     scanf("%d",&n);
     while(n--)
     {
          scanf("%s%s",s,t);
          ls=strlen(s);
          lt=strlen(t);
          ans=kmp(s,t,ls,lt);//s为模式串
          cnt=kmp(t,s,lt,ls);//t为模式串
          printf("%d
",ls+lt-max(ans,cnt));

     }
     return 0;
}
原文地址:https://www.cnblogs.com/llei1573/p/3278844.html