KMP算法例题

链接:https://codeforces.com/contest/1200/problem/E

题意:依次合并两个单词,每次合并将删去最长相同前后缀,输出结果。

思路:用kmp跑出每个需要被连接的单词的next数组,与之前的单词进行匹配,跑出最长前后缀的长度并更新结果。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e6+10;
 4 int kmp[maxn];
 5 char ans[maxn];
 6 char b[maxn];
 7 int main()
 8 {
 9     int T;
10     scanf("%d",&T);
11     T--;
12     scanf("%s",ans+1);
13     int anslen=strlen(ans+1);
14     while(T--){
15         scanf("%s",b+1);
16         int len=strlen(b+1);
17         kmp[0]=kmp[1]=0;
18         int j=0;
19         for(int i=2;i<=len;i++){
20             while(j&&b[i]!=b[j+1])
21                 j=kmp[j];
22             if(b[j+1]==b[i])j++;
23                 kmp[i]=j;
24         }
25         j=0;
26         for(int i=max(1,anslen-len+1);i<=anslen;i++){
27             while(j>0&&b[j+1]!=ans[i])
28                 j=kmp[j];
29             if(b[j+1]==ans[i])
30                 j++;
31         }
32         int t=anslen;
33         for(int i=j+1;i<=len;i++){
34             ans[++t]=b[i];
35         }
36         anslen=t;
37     }
38     for(int i=1;i<=anslen;i++)
39         printf("%c",ans[i]);
40     printf("\n");
41 }

第二套代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e6+10;
 4 int net[maxn];
 5 int main()
 6 {
 7     ios::sync_with_stdio(0);
 8     cin.tie(0);
 9     string ans;
10     int n,ans_sz;
11     cin>>n>>ans;
12     for(int i=1;i<n;i++){
13         string tmp; cin>>tmp;
14         int sz=tmp.size();
15         int p=0; net[0]=net[1]=0;
16         for(int i=2;i<=sz;i++){
17             while(p&&tmp[i-1]!=tmp[p]) p=net[p];
18             if(tmp[i-1]==tmp[p]) p++;
19             net[i]=p;
20         }
21         p=0; //最长相同前后缀长度
22         ans_sz=ans.size();
23         for(int i=max(1,ans_sz-sz+1);i<=ans_sz;i++){
24             while(p&&ans[i-1]!=tmp[p]) p=net[p];
25             if(ans[i-1]==tmp[p]) p++;
26         }
27         for(int i=p;i<sz;i++) ans+=tmp[i];
28     }
29     cout<<ans<<endl;
30     return 0;
31 }

 

posted @ 2020-02-03 13:32  古比  阅读(793)  评论(0编辑  收藏  举报