zoukankan      html  css  js  c++  java
  • 审查(银)

    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 } 
  • 相关阅读:
    浅谈Semaphore类
    Python浅谈requests三方库
    191104
    191103
    191102
    191101
    191031
    191030
    191029
    191028
  • 原文地址:https://www.cnblogs.com/lcan/p/9885683.html
Copyright © 2011-2022 走看看