查找循环等效的最大子字符串

时间:2014-10-24 06:54:44

标签: string algorithm data-structures string-matching

这是最近举行的编程竞赛的一个问题。

当且仅当存在偏移d时,两个字符串a [0..n-1]和b [0..n-1]被称为循环等效,使得对于所有0< = i< n,a [i] = b [(i + d)mod n]。 给定两个字符串s [0..L-1]和t [0..L-1]具有相同的长度L.你需要找到最大p,使得s [0..p-1]和t [0。 .p-1]是循环等价的。如果没有这样的有效p,则打印0。

输入

第一行包含一个整数T,表示测试用例的数量。 对于每个测试用例,总共有两行。第一行包含s。第二行包含t。 所有字符串仅包含小写字母。

输出

总共输出T行。每行应以" Case#:"开头。然后是最大值p。在这里"#"是从1开始的测试用例的编号。 约束

1≤T≤10 1≤L≤1000000

示例

输入:

2

ABAB

巴巴

ABAB

BAAC

输出:

案例1:4

案例2:3

解释

案例1,d可以是1.

案例2,d可以是2。

我的方法:

在S [0 ... i],T [0 ... i]中生成S和T的所有子串,并将S [0 ... i]连接到自身,并检查T是否为子串S [0 ... 1] + S [0 ... i]中。如果是子串,则最大P = i

bool isCyclic( string s, string t ){
   string str = s;
   str.append(s);
   if( str.find(t) != string::npos )
       return true;
   return false;
}

int main(){
   string s, t;
   int t1,l, o=1;
   scanf("%d", &t1);
   while( t1-- ){
       cin>>s>>t;
       l = min( s.length(), t.length());
       int i, maxP = 0;
       for( i=1; i<=l; i++ ){
           if( isCyclic(s.substr(0,i), t.substr(0,i)) ){
               maxP = i;
           }
       }
       printf("Case %d: %d\n", o++, maxP);
   }
   return 0;
}

我知道这不是解决此问题的最优化方法,因为我超时限制。我开始知道前缀函数可用于获取O(n)算法。我不知道前缀功能。有人可以解释O(n)方法吗? 比赛链接http://www.codechef.com/ACMKGP14/problems/ACM14KP3

0 个答案:

没有答案