标签:
题目大意:
给定两个字符串,在第一个字符串中找到一个最大前缀作为第二个字符串的后缀
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <queue> 7 #include <climits> 8 #include <cmath> 9 #include <cstdlib> 10 11 using namespace std; 12 13 #define ll long long 14 #define N 1000100 15 char a[N] , b[N]; 16 int _next[N] , extend[N] , len1 , len2; 17 18 void get_next(char *T){// _next[i]: 以第i位置开始的子串 与 T的公共前缀 19 int i,length = strlen(T); 20 _next[0] = length; 21 for(i = 0;i<length-1 && T[i]==T[i+1]; i++); 22 _next[1] = i; 23 int a = 1; 24 for(int k = 2; k < length; k++){ 25 int p = a+_next[a]-1, L = _next[k-a]; 26 if( (k-1)+L >= p ){ 27 int j = (p-k+1)>0? (p-k+1) : 0; 28 while(k+j<length && T[k+j]==T[j]) j++;// 枚举(p+1,length) 与(p-k+1,length) 区间比较 29 _next[k] = j, a = k; 30 } 31 else _next[k] = L; 32 } 33 } 34 void getextend(char *S,char *T){ 35 int maxl=max(len1 , len2); 36 for(int i=0 ; i<=maxl ; i++) _next[i]=0; 37 get_next(T); 38 int Slen = strlen(S), Tlen = strlen(T), a = 0; 39 int MinLen = Slen>Tlen?Tlen:Slen; 40 while(a<MinLen && S[a]==T[a]) a++; 41 extend[0] = a, a = 0; 42 for(int k = 1; k < Slen; k++){ 43 int p = a+extend[a]-1, L = _next[k-a]; 44 if( (k-1)+L >= p ){ 45 int j = (p-k+1)>0? (p-k+1) : 0; 46 while(k+j<Slen && j<Tlen && S[k+j]==T[j] ) j++; 47 extend[k] = j;a = k; 48 } 49 else extend[k] = L; 50 } 51 } 52 53 54 int main() 55 { 56 #ifndef ONLINE_JUDGE 57 freopen("a.in" , "r" , stdin); 58 #endif 59 while(~scanf("%s%s" , a , b)) 60 { 61 getextend(b , a); 62 len1 = strlen(a) , len2 = strlen(b); 63 int ret = 0; 64 for(int i=0 ; i<len2 ; i++) 65 if(extend[i]>ret&&extend[i]+i==len2) ret = extend[i]; 66 if(!ret) puts("0"); 67 else{ 68 strncpy(a , b+(len2-ret) , ret); 69 a[ret] = ‘\0‘; 70 printf("%s %d\n" , a, ret); 71 } 72 } 73 return 0; 74 }
标签:
原文地址:http://www.cnblogs.com/CSU3901130321/p/4599014.html