Manacher算法-求字符串中最长回文串
来源:互联网 发布:文件加密解密算法 编辑:程序博客网 时间:2024/05/29 13:40
一、算法原理
Manacher算法在对求字符串中最长回文串问题中,具有O(n)时间和空间复杂度。算法的精妙之处在于巧妙的利用了回文串的对偶性质。
第一步:对字符间添加间隔符,(例如,字符串aababcdab,通过添加间隔符转化为 #a#a#b#a#b#c#d#a#b#)从而避免了字符串的奇偶性问题,为了避免算法中考虑边界问题,可以在字符串首尾加入奇异符号(例如,$#a#a#b#a#b#c#d#a#b#&,因为C/C++字符串中有结束符\0,所以可可以省略尾端加入的奇异符);
第二步:更新模式数组p[],这里也是Manacher算法的核心所在,我当初看这块时纠结了好长时间。首先通过图片来说明一下:
假设当前处理位置在i点,且 i < mx(mx为关于坐标k对称子串的右边界为),即P[k] = mx - k。此时忽略左边界mx’又 i 关于 k 对称的坐标为 j ,这时就可以分成两种情况:
P[j] > mx - i + 1 时,P[i] = mx - i + 1;因为 mx 和 mx’ ,i 和 j 为关于k对称,所以 S[ mx’, ~ ,j ] = S[ i, ~ ,mx ]。如果 P[i] > mx - i + 1,也即 S[mx+1] = S[2*i - mx - 1],而已知:S[mx’ -1] = S[2*j - mx’ + 1 ],j + i= 2*k,mx’ + mx= 2*k ,所以有S[mx’-1] = S[mx+1],这时以k为中心对称子串右边界变为了mx+1,矛盾。
P[j] == mx - i + 1 时,P[i] >= P[j];证明方法和上面一样。
- P[j] <”mx - i + 1 时,P[i] = P[j];证明方法和上面一样。
对于其他情况就需要重新匹配了。
第三步:找到(也可以在更新P[]时记录最大数)模式数组P[]中最大数减一,即为字符串中最大回文串长度。
二、程序
#include <iostream>#include <string>using namespace std;int LongestPalindromicSubstring(const string& S, int& maxPos){ int *p = new int[S.size() + 1]; memset(p, 0, sizeof(p)); int mx = 0, k = 0; int maxLength = 0; bool reCompute = false; for(int i = 1; i < S.size(); i++) { if( mx > i ) { p[i] = (p[2*k - i] < (mx - i) ? p[2*k - i] : (mx - i + 1)); reCompute = p[2*k - i] == (mx - i + 1) ? true : false; } else { p[i] = 1; reCompute = true; } if( reCompute ) { for(; S[ i+p[i] ] == S[i - p[i] ]; ++p[i]); } if( p[i] > maxLength) { maxPos = i; maxLength = p[i]; } if(i + p[i] > mx) { mx = i + p[i] - 1; k = i; } cout << S[i] << " "; reCompute = false; } cout << endl; for(int i = 1; i < S.size(); i++) { cout << p[i] << " "; } cout << endl; maxPos = maxPos/2 - 1 - --maxLength/2; delete p; return maxLength;}int main(){ string S = "aabababab"; string S_Process; S_Process += "$#"; for(int i = 0; i < S.size(); i++) { S_Process += S[i]; S_Process += "#"; } cout << S_Process << endl; int pos = 0; int length = LongestPalindromicSubstring(S_Process, pos); cout << "max Longest Palindromic Substring is : " << S.substr(pos, length) << endl; cout << "max length : " << length << endl; return 0;}
结果:
- Manacher算法-求字符串中最长回文串
- 字符串专题小结:Manacher算法求最长回文串
- Manacher算法求字符串的最长回文子串
- Manacher算法求最长回文子串
- Manacher算法求最长回文子串
- Manacher算法求最长回文串
- Manacher算法求最长回文串
- manacher算法求最长回文串长度
- manacher算法求最长回文串
- Manacher算法--求最长回文子串
- Manacher算法求最长回文子串
- Manacher算法求最长回文串
- 求最长回文串(Manacher算法)
- Manacher算法求最长回文子串
- Manacher 算法 求最长字回文串
- Manacher-求最长回文字符串
- Manacher算法求最长回文
- 最长回文字符串(manacher算法)
- 解决"Could not initialize class android.graphics.Typeface"
- POJ-2457 SPFA+路径记录
- Unity3d 着色器语法(Shader)
- Android操作系统软键盘的显示与隐藏
- Masonry介绍与使用实践(快速上手Autolayout)
- Manacher算法-求字符串中最长回文串
- Return-to-libc攻击实验
- 软件测试
- 将ListView中的内容导出到Word和Excel(新)
- Linux Min装机--配置JDK替换OpenJDK
- WebSocket实战 - 基本原理
- 2012年5月SAT香港真题解析
- 网站防刷方案
- 用SQLYog导出导入数据所遇到的问题