审查(银)

Posted lcan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了审查(银)相关的知识,希望对你有一定的参考价值。

FJ把杂志上所有的文章摘抄了下来并把它变成了一个长度不超过10^5的字符串S。他有一个包含n个单词的列表,列表里的n个单词记为t_1...t_N。他希望从S中删除这些单词。

FJ每次在S中找到最早出现的列表中的单词(最早出现指该单词的开始位置最小),然后从S中删除这个单词。他重复这个操作直到S中没有列表里的单词为止。注意删除一个单词后可能会导致S中出现另一个列表中的单词

FJ注意到列表中的单词不会出现一个单词是另一个单词子串的情况,这意味着每个列表中的单词在S中出现的开始位置是互不相同的

请帮助FJ完成这些操作并输出最后的S

 

这个删完后要用链表连接,但是匹配串应该退回到哪里呢,

就是在每次枚举到一个i的时候,都记录此时的j,表示第i位往前最多可以和匹配串的前j位匹配,以便删完后往前跳的时候,匹配串应该跳到哪里

 

KMP的细节总是很多,要背过啦

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<vector>
 7 #include<stack>
 8 #include<queue>
 9 #include<map>
10 #include<set>
11 using namespace std;
12 const int maxn=1e6+7;
13 char s[maxn],t[maxn];
14 int lens,lent;
15 int nxt[maxn],mth[maxn],l[maxn],r[maxn];
16 void pre(){
17   nxt[1]=0;int j=0;
18   for(int i=1;i<lent;i++){
19     while(j&&t[i+1]!=t[j+1]) j=nxt[j];
20     if(t[i+1]==t[j+1]) j++;
21     nxt[i+1]=j;
22   }
23 }
24 int main(){
25   scanf("%s",s+1);scanf("%s",t+1);
26   lens=strlen(s+1);lent=strlen(t+1);
27   pre();
28   for(int i=1;i<=lens;i++) l[i]=i-1,r[i]=i+1;
29   r[0]=1;int j=0;
30   for(int i=0;i<lens;i=r[i]){
31     mth[i]=j;
32     while(j&&s[r[i]]!=t[j+1]) j=nxt[j];
33     if(s[r[i]]==t[j+1]) j++;
34     if(j==lent){
35       int tmp=r[r[i]];
36       for(int k=1;k<lent;k++) i=l[i];
37       l[tmp]=i;r[i]=tmp;
38       j=mth[i];i=l[i];
39     }
40   } 
41   for(int i=r[0];i<=lens;i=r[i]){
42     cout<<s[i];
43   }cout<<endl;
44   return 0;
45 } 

 

以上是关于审查(银)的主要内容,如果未能解决你的问题,请参考以下文章

「USACO15FEB」Censoring (Silver) 审查(银) 解题报告

简单的方法来分享/讨论/协作的代码片段?

2019-04-07 中国银联:“闪付”被盗刷可获全额赔付安卓全球开发者峰会将于10月23-24日在加州召开

网页上审查元素提取一段完整网页代码

Win10 平安网银控件安装不上及登录提示“签名失败...错误代码:1002”的解决方法

代码审查的必要性和最佳实践