ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

manacher-马拉车算法

2019-08-19 13:01:53  阅读:230  来源: 互联网

标签:字符 int manacher 最长 算法 拉车 id 回文


考虑到暴力求解可能会超时,manacher算法目的就是减少重复的遍历,减小时间复杂度,暴力求解时间复杂度是O(n^2),manacher算法可提升为O(N),因为manacher在遍历的时候只会往后面未遍历的字符进行暴力求解式对比,理解为要查询的当前字符本身处在一个前面遍历成功查询到的最长回文段内,如 i<mx(后面会详细讲到,也可结合代码),前面有对称点j则直接相等相应的最长回文长度,若要验证超出 j 范围的必须往后面未遍历的字符查询,因此 i 是一直向前查询,O(n)

关键:分类讨论当前字符所在区间和本身最长回文

1.i>=mx在前一个id最长回文之外,那和普通暴力求解过程一样
2.i<mx 即在前一个id最长回文内,能找到对称点j
  2.1 j本身的最长回文长度区间仍在 id回文内,那么i的最长回文至少是对称点j的长度,但因为i周围环境与j不同,还需检测i是否有更长的回文,到下一步
  2.2 j本身的最长回文有部分在id内有部分超出,那i可以确定的只有j在id回文内的那一段是相等的,超出部分由于ij周围环境不一定相等,不可等同,需同上述进行自我检测
 总结:两者合起来就是找两个中最长回文值最小的作为基础保底值,后面的长度需要自我检测

 1 #include<stdio.h>
 2 #include<string.h>
 3 #define max 1000000
 4 
 5 char str[max],s[max];
 6 int len[max]={0} ;
 7 
 8 void init()
 9 {              //初始化输入的字符加入#变为奇数长的字符串,在开头加$是为了做边界,当字符暴力求解时是前n个字符与后n个字符是否匹配得以继续扩展,
10     int n,i=1,j=0;     //$是唯一一个字符,当遇到它是就会自动停止匹配
11     str[0]='$';
12     n=strlen(s);
13     str[2*n+1]='#';
14     
15     while(i<2*n+1){
16         str[i++]='#';
17         str[i++]=s[j++];
18     }
19 }
20 
21 int min(int x,int y)
22 {
23     int z=x<=y?x:y;
24     return z;
25 }
26 
27 void manacher()
28 {
29     int i,n,mx=0,id=0;
30     n=strlen(s);
31     
32     for(i=1;i<=2*n+1;i++)
33     {    int j=2*id-i;
34         if(i<mx) len[i]=min(mx-i,len[j]);
35         else len[i]=1;            //判断i是否有对称的j可直接相等,若i=mx则就算有相对应的j长度也只是1,还是要进行下一步的暴力求解  
36                         
37         int e=1;
38         while(1){            //暴力求解检测超出j范围的最长回文是否存在,即j存在,i至少是len[j]长,但有可能比j还长,因为j是已经查询过的已经固定的 
39             if(str[i+e]==str[i-e])
40             {
41                 len[i]++;
42                 e++;
43             }else break;
44         }
45         
46         if(i>=mx)
47         {              //当i超出前一个最长回文范围时就是重新暴力求解时,需要更新新的回文范围减少重复
48             id=i;
49             mx=id+len[i]-1;
50         }
51         
52     }
53 }
54 
55 int main()
56 {
57 
58     scanf("%s",&s);
59     int n=strlen(s);
60     printf("\nn=%d\n",n);
61     init();
62         printf("%s",str);
63     manacher();    
64     printf("\n");
65     for(int i=0;i<=2*n+1;i++){
66         printf("%d",len[i]);
67     }
68         
69 }
70  

 

 

标签:字符,int,manacher,最长,算法,拉车,id,回文
来源: https://www.cnblogs.com/Theo-sblogs/p/11376459.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有