题目链接:点击打开链接
分析:
本题要求统计一个字符串中包含多少个回文子串,回文就是正读、倒读都是一样的,单个字符串也是回文子串。
为了避免超时错误,这里采用由中心向外扩散的方法判断一个子串是否是回文子串:如果中心的子串不是回文,那么立即终止,不必去判断向外扩散的子串了。
大致思想是:
1.查找子串。首先从左向右读,钉住左边第一个字符,逐个选取子串。然后从右向左读,钉住右边第一个字符,一直读到左边倒数第二个字符(从左往右读的时候已经度过一次整个字符串),逐个选取子串。
2.判断是否是回文。根据子串长度找到子串中心,从中心分为左串和右串,如果字符串长度为奇数,左串从中心左边第一个字符开始,右串从中心右边第一个字符开始;如果字符串长度为偶数,左串从中心开始,右串同上。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int main()
{
char s[5000];
int p,i,Half,Left,Right,Count;
while (cin>>s)
{
i=strlen(s);
Count=0;
for(p=0;p<i-1;p++)
{
Half=((i-1)-p)/2;
//如果子串是奇数个字符
if(((i-1)-p)%2==0)
{
Left=p+Half-1;
Right=p+Half+1;
}
//如果子串是偶数个字符
else
{
Left=p+Half;
Right=p+Half+1;
}
while(Left>=p)
{
if(s[Left]==s[Right])
{
Count++;
Left--;
Right++;
}
else break;//如果不相等,立即中止,由中心向外扩散不可能有回文串
}
}
for(p=i-2;p>=1;p--)
{
Half=p/2;
//如果子串是奇数个字符
if(p%2==0)
{
Left=Half-1;
Right=Half+1;
}
//如果子串是偶数个字符
else
{
Left=Half;
Right=Half+1;
}
while(Left>=0)
{ //发现回文串
if(s[Left]==s[Right])
{
Count++;
Left--;
Right++;
}
else break;//如果不相等,立即中止,由中心向外扩散不可能有回文串
}
}
printf("%d\n",Count+i);
}
return 0;
}