有一定难度,难在考虑不周全,最后还是看了别人提到的方法,自己独立实现了一下,可能没有别人的简洁,但是易懂,调试的时候有些小毛病,但自己解决了,原因不是很清楚,最后总结里会提到。
目标:在输入的字符串里找到对称的且是最长的那个字符串
思路:(参考别人后)为了模拟全部的可能,需要考虑两种情况,且从头开始遍历
1. 偶数型:**AbbA**、**AAAA**
2. 奇数型:**AbA**
利用中心扩展法:
1.奇数时,1个 i 指针——让其分别向左右两边扩展,如果遇到左右两边相同则记录当前长度,继续扩展,不同则跳出,继续循环。
2.偶数时,i 、j 2个指针——让其 i 向左边扩展,j 向右边扩展,如果 当前两个位置元素相同,且扩展后的位置元素也相同,则记录当前长度,继续扩展,否则跳出,继续循环。
代码:
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int theLen1(string s)
{
int count = 2;
for (int i = 1; i < s.length(); i++)
{
int pre = i - 1;
int next = i + 1;
if (pre < 0 || next == s.length() || s[pre] != s[next] )
{
continue;
}
while ((pre >= 0 && next < s.length())&&s[pre] == s[next])
{
count = max(count, next - pre + 1);
pre--;
next++;
}
}
return count;
}
int theLen2(string s)
{
int count = 2;
for (int i = 0,j=i+1; j < s.length(); i++,j++)
{
if (s[i] == s[j])
{
int pre = i - 1;
int next = j + 1;
if (pre < 0|| next == s.length() || s[pre] != s[next] )
continue;
while((pre >= 0 && next < s.length())&&s[pre] == s[next])
{
count = max(count, next - pre + 1);
pre--;
next++;
}
}
else continue;
}
return count;
}
int main()
{
string s;
while (cin>>s)
{
cout << max(theLen1(s), theLen2(s));
}
return 0;
}
总结:
1.因为题目给的案例必有对称,所以最少字符串长度为2,所以 count初始化为2;
2.i 必须从头开始,且采用两种方式遍历才能够将所有情况涵盖;
3. while 循环里 while ((pre >= 0 && next < s.length())&&s[pre] == s[next]),循环条件顺序不可颠倒,因为 前者的条件可能在执行后者的条件之前就已经发生了。简单的说就是,写循环条件时需要把可能会越界的条件写在前面!防止debug的时候异常中止。