有一个字符串,要求其最长回文子串,如”QINGENENG”的最大回文子串为“NEN”
分析:可以依次遍历,然后判断左右是否形同,知道不同为止,记下长度与相应下标,遍历到末尾结束,即可找出
代码如下:
// [10/3/2013 qingezha] 真没想到可以从中间向两边出发,分别比较2边是否相同,注意回文个数是偶数/奇数情况
int getpalindrome(char *arr,int len)//获取最大的回文
{
int i = 0;
int j = 0;
int max = 0;
for (i=0;i<len;++i)
{
for(j=1;i+j<len&&i-j>=0;++j) //回文是奇数的情况
if(arr[i-j] !=arr[i+j])
break;
if(2*j-1>max)
max = 2*j - 1;
for (j=1;i-j>=0&&i+j+1<len;++j) //回文长度为偶数,认为与相邻的后面相同
if(arr[i-j]!=arr[i+j+1])
break;
if(i+j+1==len&&2*j + 2>max)
max = 2*j + 2;
if(i+j+1==len&&2*j - 2>max) //这里j在元素不等时跳出与for中条件不满足时跳出
max = 2*j - 2;
}
return max;
}
百度了一下,还有更巧妙的方法是相邻2个字符中间插入非字母符号,这样就不用分长度为奇偶情况讨论了,实在是高!!
代码如下:
//另外一种方法是abcgoogleaba,可以进行这样的操作:#a#b#c#g#o#o#g#l#e#a#b#a#
//中间插入#或其他字符
int getpalindrome_ss(char *arr,int len)//获取回文的最大长度
{
int len2 = 2*len + 1;
int j = 0;
int i = 0;
int max = 0;
char *str = new char[len2];
for (int i=0;i<len;++i)
{
str[2*i] = '#';
str[2*i+1] = arr[i];
}
str[len2-1] = '#'; //中间插入“#”
for(i=0;i<len2;++i)
{
for(j=1;i+j<len2&&i-j>=0;++j)
if(arr[i-j] !=arr[i+j])
break;
if(2*j-1>max)
max = 2*j - 1;
}
delete[] str;
return max;
}