这个数据比较弱, 暴力就可以过……还可以DP, 后缀树组……
暴力就不说了……
DP:
后缀树,现在还不会啊……
暴力:
#include<iostream> #include<cstring> using namespace std; bool Judge(int s, int e, char str[]) { int i, j; for(i=s, j=e; i<=j; i++, j--) if( str[i]!=str[j]) return 0; return 1; } int main() { char str[1001]; cin>>str; int i, j; int len=strlen(str), s=0, e=0, maxx=0; for(i=0; i<len; i++) for(j=len-1; j>i; j--) { if( Judge(i, j, str)) { if( j-i+1>maxx) { s=i; e=j; maxx=j-i+1; } break; } } for(i=s; i<=e; i++) cout<<str[i]; cout<<endl; }
Manacher算法:
#include<iostream> #include<cstring> using namespace std; #define N 1100 char str[N], str1[2*N]; int len; //将输入的字符串转化为str1,使得str1的每个回文子串长度都变为奇数 //方法:在每个字符两边都插入一个特殊字符 //另外在串的开始加入另一个特殊字符, 可以避免对数组越界问题做特殊处理 void Init() { cin>>str; int i=0, j; str1[0]='@';//开始加入另特殊字符 str1[1]='#'; j=2; for(i=0; str[i]!='\0'; i++ )//在每个字符两边都插入一个特殊字符 { str1[j++]=str[i]; str1[j++]='#'; } str1[j]='\0'; } //算法主体 void Solve( ) { int i, j, mx, id, p[2*N]; int maxx=0, record=0; //mx=id+p[id],表示在以id为中心的回文右边界 mx=0; memset(p, 0, sizeof(p)); for(i=1; str1[i]!='\0'; i++) { if( mx>i ) p[i]=min(mx-i, p[2*id-i]); else p[i]=1; //扩展p[i] ,在开始加入另一个特殊字符,是为了在这避免对i-p[i]做限制 //如果在开始不加入特殊字符,则需要循环时i从0开始, //并且改为while( str1[i+p[i]]==str1[i-p[i]] && i-p[i]>=0) : //如果不加i-p[i]>=0, 遇到整串是同一个字母的会越界;如aaaa while( str1[i+p[i]]==str1[i-p[i]] )//扩展p[i] p[i]++; if( i+p[i]>mx ) { mx=i+p[i]; id=i; } if( p[i]-1>maxx)//maxx记录最长回文的长度 { maxx=p[i]-1;//P[id]-1就是该回文子串在原串中的长度 record=i;//record记录最长回文中心 } } for(i=record-maxx; i<=record+maxx; i++)//输出 if( str1[i]!='#') cout<<str1[i]; cout<<endl; } int main() { Init(); Solve(); }