HDU 6629 string matching(扩展KMP)

多校打下来第一次成功补题(?你在干嘛)

套板子完事,主要是之前没搞懂扩展KMP到底是什么,KMP也没搞清楚,这回顺带加深了一下印象。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6629

题意:给出一个用于求在一个给定字符串中求每一位的后缀(含自己)与这个字符串的最长相同的长度的算法,问你对于给出的字符串执行这个算法,会进行多少次这个算法中那个字符与字符的比较过程(详见题目)。

思路:用拓展KMP里求辅助数组的代码跑一遍,我们就可以得到每一位的最长字串的长度,然后因为问的是比较次数,那么只要这一位的位置加上它的子串长没用超过字符串的最后一位,就说明它会在统计时还要加上一次比较次数,也就是在统计它的字串长度时它和下一位比较并且匹配失败的那一次。

说得比较绕,还是放代码吧。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<set>
 4 #include<stdio.h>
 5 #include<string.h>
 6 #include<math.h>
 7 #include<vector>
 8 #include<stdlib.h>
 9 #include<queue>
10 #include<algorithm>
11 #include<map>
12 #include<stack>
13 using namespace std;
14 char c[1000005];
15 int nex[1000005];
16 int main()
17 {
18     int t;
19     scanf("%d",&t);
20     while(t--)
21     {
22         scanf("%s",c);
23         long long s=0;
24         int len=strlen(c);
25         nex[0]=len;
26         int a=0,p=0;//p 当前最长匹配距离 a最长匹配距离对应的点
27         for(int i=1;i<len;i++)
28         {
29             if(i>=p||i+nex[i-a]>=p)//假如i在最长匹配距离的点之外或其预期距离超出p
30             {
31                 if(i>=p)
32                 {
33                     p=i;
34                 }
35                 while(p<len&&c[p]==c[p-i])
36                 {
37                     p++;
38                 }
39                 nex[i]=p-i;
40                 a=i;
41             }
42             else//假如没有超出的可能,直接得出结论
43             {
44                 nex[i]=nex[i-a];
45             }
46         }
47         for(int i=1;i<len;i++)
48         {
49             //printf("%d\n",nex[i]);
50             s+=nex[i];
51             if(i+nex[i]<len)//访问距离未超出字符串末尾就会再访问下一位
52             {
53                 s++;
54                 //printf("1\n");
55             }
56         }
57         printf("%lld\n",s);
58     }
59     return 0;
60 }

 

转载于:https://www.cnblogs.com/forever3329/p/11305344.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值