九度笔记之 1252:回文子串
2013-07-23 11:17
232 查看
题目描述:
输入一个字符串,输出该字符串中对称的子字符串的最大长度。比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4。
输入:
存在多组数据,每组数据一行字符串,长度不大于100。
输出:
输出回文子串的最大长度。
样例输入:
样例输出:
4
算法分析:
本来打算用《最长合法括号序列1》中的算法,利用动态规划做,但是对于例如“aaa”的情况该算法就无效了因为括号必须是左右一对同时出现,左边的必为”(“,右边的必为”)“,所以当出现str[pos]==”(”或 str[sympos]<0 或str[sympos]==”)”的情况时,str[pos]位置的符号不可能再和dp[pos-1]合法子括号序列的子字符串构成合法括号序列。
(()(
)()(
())
)())
对于回文字符串,则会出现以下情况
aaa
dp[1]=2 ,
pos==2时,sympos== -1,得到dp[pos]=1 实际上dp[pos]=3
因为a[1]相当于一个回文字符串,str[0]==str[2],dp[pos]=3
abadabad
dp[6]=7,
pos==8时,sympos== -1,得到dp[pos]=1 实际上dp[pos]=5
因为abadaba中的子字符串aba为一个回文字符串,str[3]==str[7],故dp[pos]=5
公共子序列查找
新的思路就是,如果字符串s中含有回文字符串,回文字符串一定为该字符串的逆序列rs和该字符串s的公共子序列,如下所示。
google s
elgoog sr
abamngnm s
mngnmaba sr
mngnmaba sr
算法实现就很简单了,从sr的某个位置开始,s从0开始逐个字符比较,记录最长的公共序列。
另外一种快速的 manach算法 参见
1252:回文子串
源代码:
程序中需要注意的是srbegin的每次循环,temLen都要重新置为0srid的每次循环结束后,也要判断一下temLen和maxLen的大小,
google s
elgoog sr
在sid==3,srid==5时,
sr.at(srid)==s.at(sid)
temLen++;
srid++;sid++;
循环退出,此时temLen==4,maxLen==0
还有就是考虑到sr需要前向错位,后向错位来比较,所以需要将s,sr反过来比较一下。参看int getMaxNum(std::string &s)
#include <iostream> #include <string> using namespace std; int getMaxNum(std::string &s,std::string &sr){ int sLen = s.size(); int maxLen = 0; int temLen = 0; /* * google s * elgoog sr */ /* * abacdefgfedcmnm * mnmcdefgfedcaba */ int srbegin = 0; while(srbegin < sLen){// sr start from i compare s int srid = srbegin; int sid = 0; temLen = 0; //attention while(srid < sLen){ if(sr.at(srid)==s.at(sid)){ temLen++; }else{ if(temLen > maxLen) maxLen = temLen; temLen=0; //break; } srid++; sid++; }//while(srid < sLen) if(temLen>maxLen) //attention srid==sLen must be considered for "google" maxLen = temLen; srbegin++; } return maxLen; } int getMaxNum(std::string &s){ std::string sr(s.rbegin(),s.rend()); int maxLen = 0; maxLen = getMaxNum(s,sr); int rMaxLen = getMaxNum(sr,s); if(rMaxLen>maxLen) return rMaxLen; else return maxLen; } void test(){ std::string s = "ab"; std::string sr(s.rbegin(),s.rend()); std::cout<<sr<<std::endl; } void judo(){ std::string s; //int temLen = 0; while(std::cin>>s){ std::cout<<getMaxNum(s)<<std::endl; } } int main() { //cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!! judo(); return 0; } /************************************************************** Problem: 1252 User: KES Language: C++ Result: Accepted Time:10 ms Memory:1520 kb ****************************************************************/
相关文章推荐
- 九度笔记之 1252:回文子串
- 九度OJ 1252:回文子串 (字符串处理、DP)
- 九度OJ 1252:回文子串 (字符串处理、DP)
- 九度 题目1252:回文子串
- 九度笔记之 1528:最长回文子串 用manacher算法
- 九度题目:最大回文子串(1252)
- 九度题目1528:最长回文子串 腾讯二面面试算法题
- 【最长回文子串】Hihocoder/Week1 学习笔记
- 九度题目1528:最长回文子串
- 数据结构学习笔记4-最长回文子串(Manacher算法)
- 【字符串处理】最长回文子串笔记(Manacher算法)
- 1040. Longest Symmetric String-PAT 1528:最长回文子串-九度
- 题目1252:回文子串
- 九度OJ 1528 最长回文子串 -- Manacher算法
- 九度OJ 1528 最长回文子串 -- Manacher算法
- 九度 题目1528:最长回文子串
- 题目1252:回文子串
- 【LeetCode】Longest Palindromic Substring && 【九度】题目1528:最长回文子串(腾讯2013年实习生招聘二面面试题)
- Hihocoder 1032 最长回文子串 Manacher && 亲测暴力可过
- hdu 3068 最长回文 【Manacher求最长回文子串,模板题】