最长回文子串
2015-07-07 15:08
316 查看
简单来说,就是顺着和逆着读相同的子串;例如erabcba的最长回文串是abcba
方法一:
动态转移方程:P[i][j]记录i—j是否为回文串(true false),P[i][j]=P[i-1][j-1](if a[i]==a[j]);
枚举子串的长度l,通过对每个字符开始l长的子串判断是否为回文串;
同时注意单个字符的回文串是;且若相邻两个字符相同,则这两个字符的回文串是2;以上两种情况要单独在初始化的时候考虑。
输出回文串,要用max去记住当前最长的回文串长度,start记住最长回文串的起始位置;
方法二:中心扩展——枚举的是字符串的中心,不断的往两边扩展比较,只需要用max来记住当前最长的回文串长度。
方法三:Manchester
参考:http://blog.csdn.net/yzl_rex/article/details/7908259
方法一:
动态转移方程:P[i][j]记录i—j是否为回文串(true false),P[i][j]=P[i-1][j-1](if a[i]==a[j]);
枚举子串的长度l,通过对每个字符开始l长的子串判断是否为回文串;
同时注意单个字符的回文串是;且若相邻两个字符相同,则这两个字符的回文串是2;以上两种情况要单独在初始化的时候考虑。
输出回文串,要用max去记住当前最长的回文串长度,start记住最长回文串的起始位置;
int huiwen1(string a) //动态规划算法,枚举的是长度从小到大;动态转移方程:(P[i][j]=0如果ij不是回文串)P[i+1][j-1]=1且a[i]=a[j]则P[i][j]=P[i+1][j-1] //时间复杂度O(N^2),空间复杂度O(N^2) { int len = a.length(); int start = 0;//记最长子串的起始坐标为start int P[10][10] = { false }; //P记录以i开始j结尾的子串是不是回文串 int max = 0;//记录最长的回文串长度 //要考虑一个字母是自己的回文,两个字符相等的话回文长度为2;故长度=1、2的子串要单独讨论 for (int i = 0; i < len; i++) { P[i][i] = true; max = 1; } for (int i = 1; i < len; i++) { if (a[i] == a[i - 1]) { P[i - 1][i] = true; max = 2; start = i - 1; } } //从长度为3的子串开始遍历 for (int l = 3; l <= len; l++)//考虑长度为l的子串 { for (int i = 0; i <= len - l; i++) //为了保证ij<len,则要保证i<=(len-1) { int j = i + l - 1;//开始坐标为i,结束坐标为j的子串 if ((a[i] == a[j]) && (P[i+1][j-1] == true)) { P[i][j] = true; //此时子串的长度就是l,所以P不用计入长度,简单的可以用true和false表示 if (max == l) start = i; } } } for (int t = start; t < start + max; t++) cout << a[t] << " "; cout << endl; cout << "最长子串长度:" << max << endl; return max; }
方法二:中心扩展——枚举的是字符串的中心,不断的往两边扩展比较,只需要用max来记住当前最长的回文串长度。
int huiwen2(string a)//中心扩展法,枚举的是每一个坐标,算以这个坐标为中心能向两边扩展的最大长度 //时间复杂度O(N^2) 空间复杂度O(1) { //要考虑奇偶的情况,如aba与abba int start = 0; int max = 1; for (int i = 0; i < a.length(); i++) { //奇数情况 int l = i - 1; int r = i + 1; while ((l >= 0) && (r < a.length()) && (a[l] == a[r]))//如果以i为中心前后相等构成回文串 { max = ((r - l + 1)>max ? (r - l + 1) : max); if (max == (r - l + 1)) start = l; l--; r++; } //偶数情况 l = i; r = i + 1;//考虑连续两个相同字符的情况 while ((l >= 0) && (r < a.length()) && (a[l] == a[r])) { max = ((r - l + 1)>max ? (r - l + 1) : max); if (max == (r - l + 1)) start = l; l--; r++; } } for (int t = start; t < start + max; t++) cout << a[t] << " "; cout << endl; cout << "最长回文子串长度:" << max << endl; return max; }
方法三:Manchester
参考:http://blog.csdn.net/yzl_rex/article/details/7908259
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- C++ Custom Control控件向父窗体发送对应的消息
- C++中拷贝构造函数的应用详解
- VisualStudio 使用Visual Leak Detector检查内存泄漏