题目:找字符串中的最大回文
分析:
1、将回文长度从nLen遍历到1;如果找到一个符合条件的回文,那就直接跳出全部循环。这样做的好处就是可以减少不必要的比较。
2、如果回文长度记为l,half为l的一半向下取整。i表示中点在源字符串中的位置
l为奇数,则每次需要比较buf[i-j]和buf[i+j]是否相等,不相等就跳出循环,因为关于half对称,故j=1~half,i=half~nLen-half-1
l为偶数,则每次需要比较buf[i-j-1]和buf[i+j]是否相等,不相等就跳出循环,因为不是关于half对称,故j=0~half-1,i=half~nLen-half
参考代码:
#include <stdio.h>
#include <string.h>
char buf[100000];
void main()
{
int l,i,j;
int nLen;
int flag;
int half;
int nMax,s,e;
while(gets(buf))
{
nLen = strlen(buf);
flag = 0;
///先奇后偶,如果本身就是偶数,先判断整个字符串是不是回文
if((nLen & 1) == 0)
{
half = nLen >> 1;
for(j = 0; j < half; ++j)
{
if(buf[half - j - 1] != buf[half + j])
{
break;
}
}
if(j == half)
{
nMax = nLen;
puts(buf);
printf("\n最多%d个回文\n", nMax);
continue;
}
}
for(l = nLen - 1 + (nLen & 1); l >= 1; l -= 2)//回文的长度为l(l为奇数),从大到小遍历,找到一个就跳出
{
half = l >> 1;
//先看奇数的
for(i = half; i < nLen - half; ++i)
{
for(j = 1; j <= half; ++j)
{
if(buf[i - j] != buf[i + j])
{
break;
}
}
if(j > half)//有符合的回文串,跳出
{
nMax = l;
s = i - half;
e = i + half;
flag = 1;
break;
}
}
if(flag)//有符合的回文串,跳出
{
break;
}
//考虑偶数部分
for(i = half; i <= nLen - half; ++i)
{
for(j = 0; j < half; ++j)
{
if(buf[i - j - 1] != buf[i + j])
{
break;
}
}
if(j == half)//有符合的回文串,跳出
{
nMax = l - 1;
s = i - half;
e = i + half - 1;
flag = 1;
break;
}
}
if(flag)//有符合的回文串,跳出
{
break;
}
}
for(i = s; i <= e; ++i)
{
putchar(buf[i]);
}
printf("\n最多%d个回文\n", nMax);
}
}