马拉车算法的笔记

最近在搞kmp以及字符串哈希Trie树等等发现了一个有趣的算法叫马拉车算法

(不得不说这个算法想到的人真的太厉害了)

下面是我关于这个算法整理的一些笔记

#include <iostream>
#include <string>
#include <cstring>
using namespace std;
const int N = 10000;
int p[N];
//马拉车算法自己的理解
//可以找到最大回文子串o(n)的复杂度
int main(){ string s; cin>>s; string s_aft="$#"; for(int i=0;i<s.size();i++){ s_aft+=s[i]; s_aft+='#'; } int mx=0,id=0,reslen=0,rescenter=0; for(int i=1;i<s_aft.size();i++){ //p表示以i为中心的最大回文串的半径大小包括i自己 //mx和id 为两个辅助变量 //id表示的是中心点的位置 //mx表示的是回文串能延伸到的最右端的位置 //由于mx表示的位置是最右端的位置后一位那么mx就直接更新为i+p[i] p[i]=mx>i?min(p[2*id-i],mx-i):1; //2*id-i是i关于id的对称点 while(s_aft[i+p[i]]==s_aft[i-p[i]])++p[i]; if(mx<i+p[i]){ //mx的位置是半径后一个位置 mx=i+p[i]; id=i;//id只可能是小于等于i所以i的对称点一定是在id的左侧故已经算出它的边长了所以更新的时候不会出现为0的情况 } if(reslen<p[i]){ //一定会更新至少为2因为第二个字母左右都添加了#所以必定为半径为2中心也为2 reslen=p[i]; rescenter=i; } } cout<<s.substr((rescenter-reslen)/2,reslen-1)<<endl; }

猜你喜欢

转载自www.cnblogs.com/kstranger/p/12285318.html