Manacher算法 (马拉车算法)
1 #include<iostream> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 6 char s[1000]; 7 char s_new[2000]; 8 int p[2000]; 9 10 int Init() 11 { 12 int len = strlen(s); 13 s_new[0] = '$'; 14 s_new[1] = '#'; 15 int j = 2; 16 17 for (int i = 0; i < len; i++) 18 { 19 s_new[j++] = s[i]; 20 s_new[j++] = '#'; 21 } 22 23 s_new[j] = '\0'; //别忘了哦 24 25 return j; //返回s_new的长度 26 } 27 28 int Manacher() 29 { 30 int len = Init(); //取得新字符串长度并完成向s_new的转换 31 int maxLen = -1; //最长回文长度 32 33 int id; 34 int mx = 0; 35 36 for (int i = 1; i < len; i++) 37 { 38 if (i < mx) 39 p[i] = min(p[2 * id - i], mx - i); //需搞清楚上面那张图含义, mx和2*id-i的含义 40 else 41 p[i] = 1; 42 43 while (s_new[i - p[i]] == s_new[i + p[i]]) //不需边界判断,因为左有'$',右有'\0' 44 p[i]++; 45 46 //我们每走一步i,都要和mx比较,我们希望mx尽可能的远,这样才能更有机会执行if (i < mx)这句代码,从而提高效率 47 if (mx < i + p[i]) 48 { 49 id = i; 50 mx = i + p[i]; 51 } 52 53 maxLen = max(maxLen, p[i] - 1); 54 } 55 56 return maxLen; 57 } 58 59 int main() 60 { 61 while (printf("请输入字符串:\n")) 62 { 63 scanf("%s", s); 64 printf("最长回文长度为 %d\n\n", Manacher()); 65 } 66 67 return 0; 68 }