博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

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 }

 

posted @ 2019-04-29 10:10  GUET_uzi  阅读(142)  评论(0编辑  收藏  举报

- 创建于 2018年9月1日

这是一位ACM爱好者&数学爱好者的个人站,内容主要是算法&数据结构&数学研究的技术文章,大部分来自学习,部分来源于网络,希望对大家有所帮助。