题目描述
Catcher 是MCA国的情报员,他工作时发现敌国会用一些对称的密码进行通信,比如像这些ABBA,ABA,A,123321,但是他们有时会在开始或结束时加入一些无关的字符以防止别国破解。比如进行下列变化 ABBA->12ABBA,ABA->ABAKK,123321->51233214 。因为截获的串太长了,而且存在多种可能的情况(abaaab可看作是aba,或baaab的加密形式),Cathcer的工作量实在是太大了,他只能向电脑高手求助,你能帮Catcher找出最长的有效密码串吗?
输入描述:
输入一个字符串
输出描述:
返回有效密码串的最大长度
示例1
输入 ABBA
输出 4
分析:字符串中的第一个单词s[i],反方向查找相同的一个单词s[j],看i到j之间是否构成回串,不构成就找下一个相同的单词,构成回串就更新最大长度。接着下一个单词重复此过程。
#include<iostream>
#include<string>
using namespace std;
inline bool isdc(string s, int i, int j){ //判断i,j之间是否构成回串;
if (i == j) return true;
while (i < j){
if (s[i] == s[j]) {
++i; --j;
}
else return false;
}
return true;
}
int main(){
string s;
while (cin >> s){
int k = 0;
for (int i = 0; i < s.size()&&k<s.size()-i; ++i){ //i到末尾的字符个数大于k,减少计算量;
size_t j = s.rfind(s[i]);
while (j != string::npos&&j-i+1>k) //从i到j的字符个数要大于k,减少计算量;
{
if (isdc(s, i, j)) k = k < j - i + 1 ? j - i + 1 : k;
j = s.rfind(s[i], j - 1); //查找第二个相同字符;
}
}
if (k < 1) cout << 1 << endl;
cout << k << endl;
}
return 0;
}
补充知识:
size_t find(char c, int pos)const; //从post位置向后查找;
size_t rfind(char c, int pos)const; //从post位置向前查找;
size_t rfind(const char *s, int pos = npos) const;
size_t rfind(const char *s, int pos, int n = npos) const;
size_t rfind(const string &s, int pos = npos) const;
成功找到,返回字符的下标,否则返回string::npos.