描述
Catcher是MCA国的情报员,他工作时发现敌国会用一些对称的密码进行通信,比如像这些ABBA,ABA,A,123321,但是他们有时会在开始或结束时加入一些无关的字符以防止别国破解。比如进行下列变化 ABBA->12ABBA,ABA->ABAKK,123321->51233214 。因为截获的串太长了,而且存在多种可能的情况(abaaab可看作是aba,或baaab的加密形式),Cathcer的工作量实在是太大了,他只能向电脑高手求助,你能帮Catcher找出最长的有效密码串吗?
数据范围:字符串长度满足 1≤n≤2500
输入描述:
输入一个字符串(字符串的长度不超过2500)
输出描述:
返回有效密码串的最大长度
示例1
输入:
ABBA
输出:
4
示例2
输入:
ABBBA
输出:
5
示例3
输入:
12HHHHA
输出:
4
解题思路:
这题和最长回文子串那道题是一样的,只是题目描述不一样。
我的想法是将输入字符串的长度先算出来,由于要求最长回文子串的长度,我选择从从子串的最长长度,即原字符串开始,判定其是否为回文字符串,若不是,则将长度减一,依次进行判定。举个例子,字符串"12HHHH",先从原字符串开始判定,发现不是回文字符串,那么子串长度减1,此时满足这个长度的子串有"12HHH"和"2HHHH",这两个仍然不是回文子串,那么子串长度再减1,此时满足这个长度的子串有"12HH"、"2HHH"、"HHHH",这个长度下有子串满足回文子串的要求,则停止循环,再输出最长回文子串的长度为4。
至于怎么判断是否为回文字符串,我们可以使用双指针的方法,对于一个字符串,left指向首字符,right指向尾字符,如果str[left]==str[right],则left++,right--,逐个比较对称字符是否相等,若全都相等,即为回文字符串。
写代码过程中要注意,每个子串开始的位置和结束的位置要写对。以下为代码实现:
#include <stdio.h>
#include <string.h>
#define N 2500
int main()
{
char str[N];
gets(str);
int len=strlen(str),i=0,j,k,left,right,flag;
while(len-i>0) //len-i为子串的长度,i初始化为0,即从最长子串(原字符串)开始判定
{
flag=0;
for(j=0;j<=i;j++) //j为子串开始的位置,即子串首字符在原字符串中的下标
{
left=j;right=len-i+j-1; //right指向子串尾字符,注意写对
while(left<right)
{
if(str[left]!=str[right]) //遇到对称字符不相等,说明不是回文字符串,跳出循环
break;
left++;right--; //否则下标往中间靠拢,逐个比较对称字符
}
if(left>=right)
{
flag=1; //查找到回文字符串,flag置1,跳出循环,提高效率
break;
}
}
if(flag==1)
break;
i++;
}
printf("%d\n",len-i);
return 0;
}