一、题目
题目描述:
找出最长回文串 (“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串)(测试用例仅做参考,我们会根据代码质量进行评分)
输入描述:
输入一行小写字母组成的字符串。
输出描述:
输出最先出现的最长回文串。
示例:
输入
babad
输出
bab
二、分析
这题折腾了挺长时间,主要是走了偷懒的歪路!
一看到题目,就想着我把字符串倒过来生成一个新串,然后用str.find(子串)直接查找不就搞定了嘛,开干!
结果只对了80%,然后就各种找代码bug…
怎么折腾都是这结果,最后想到可能是find的结果并不一定是我倒过来的那部分!
找到毛病就好办了,自己重写一个判断是不是回文的函数,略改一下就过了。
生成子串有两种方法,一种从小到大,另一种从大到小,显然从大到小要方便,且费时更少!
三、代码
代码如下:
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <algorithm>
using namespace std;
bool test(string subs){
bool res;
for (int i=0; i<subs.length(); ++i){
if(subs[i] == subs[subs.length()-1-i]){
res = true;
}else{
res=false;
break;
}
}
return res;
}
std::string solution(std::string str){
std::string result;
// TODO:
int l = str.length();
if (l==1) result = str;
int res_len=0;
string tmp;
for (int j=0; j<l; ++j){
for (int k=0; k<l-1; ++k){
tmp =str.substr(j,l-k);
if (test(tmp) && (str.substr(j,l-k)).length()>res_len){
result=str.substr(j,l-k), res_len=result.length();
}
}
}
return result;
}
int main() {
std::string str;
getline(std::cin, str);;
std::string result = solution(str);
std::cout<<result<<std::endl;
return 0;
总结
别偷懒,老实做事!
现在想想其实用分治法来解更为科学,如描述中的:“level”或者“noon”,回文串有两种可能:奇数的“level”或者偶数的“noon”,那么我们可以编写二个函数,分别用于查找奇数和偶数的回文。
奇数查找思想可以先假设index 1 为回文中心,向左右扩散,如果是就记录回文长度。如果不是就把index 移到 2,如此循环一次。就得出最长奇数回文串。
偶数回文串可以先假设index 1 和 2 为回文中心。处理方式和奇数回文一样。
最后max比较一下哪个更大即可,下次遇到此题再用此法解。