回文_Manacher算法

算法简介:算法的目的是在O(n)的时间复杂度内找到一个字符串中各个字母所在的最大长度的回文串。

此算法用到了一个Rad[]数组的定义,Rad[i]表示回文的半径,即最大的j满足str[i-j+1...i] = str[i+1...i+j]。

我们的工作就是把全部的Rad[]求出来。

有两个结论:

 (1): 对于一个整数k,如果 (1<=k<=Rad[i] && Rad[i-k] < Rad[i]-k ) 那么, Rad[i+k] = min( Rad[i-k], Rad[i]-k ).

(2) :  对于一个整数k,如果 (1<=k<=Rad[i] && Rad[i-k] > Rad[i]-k ) 那么, Rad[i+k] = min( Rad[i-k], Rad[i]-k ).

参考http://www.starvae.com/?p=212

模版:参考poj3974

View Code
 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <string>
 5 using namespace std;
 6 //13400K 485MS 
 7 const int maxnum=2000005;
 8 int rad[maxnum];
 9 
10 int manacher(char *str)
11 {
12     memset(rad,0,sizeof(rad));
13     string s;
14     int n=strlen(str);
15     int ans=0;
16     int i,j,k;
17     for(i=0;i<n;i++)
18     {
19         s+='#';
20         s+=str[i];
21     }
22     s+='#';
23     n=(n<<1)+1;
24     i=0;
25     j=1;
26     while(i<n)
27     {
28         while(i-j>=0 && i+j<n && s[i-j]==s[i+j])
29             j++;
30         rad[i]=j-1;
31         k=1;
32         while(k<=rad[i] && rad[i]-k!=rad[i-k])
33         {
34             rad[i+k]=min(rad[i-k],rad[i]-k);
35             k++;
36         }
37         i+=k;
38         j=max(j-k,0);
39     }
40     for(i=0;i<n;i++)
41         ans=max(ans,rad[i]);
42     return ans;
43 }
44 
45 int main()
46 {
47     int num=1;
48     char str[maxnum];
49     while(scanf("%s",str)!=EOF)
50     {
51         if(strcmp(str,"END")==0)
52             break;
53         else
54         {
55             printf("Case %d: ",num++);
56             printf("%d\n",manacher(str));
57         }
58     }
59     return 0;
60 }

 

posted @ 2012-08-26 17:08  pushing my way  阅读(877)  评论(1编辑  收藏  举报