• 【Foreign】字符串匹配 [KMP]


    字符串匹配

    Time Limit: 10 Sec  Memory Limit: 256 MB

    Description

      

    Input

      

    Output

      

    Sample Input

      3 3
      6 3
      1 2 1 2 3 2
      3 1 3
      6 3
      1 2 1 2 1 2
      3 1 3
      6 3
      1 1 2 1 2 1
      3 1 3

    Sample Output

      3
      1 2 4
      4
      1 2 3 4
      3
      2 3 4

    HINT

      

    Solution

      发现题目中颜色的具体权值是对答案无关的,然后就是只要相对位置一样即可。

      那么显然是一个KMP的模型,变相更改,条件改为:两个字符上一次出现的相对位置相同(也就是位置差值相等)

      那么我们只要求出差值来KMP即可,再考虑一下串长对于答案的影响,差值>串长显然是不会影响答案的,但是直接匹配的话可能将这种情况默认为不可行,所以我们在匹配的时候判断一下串长,若dist>=当前匹配串长则同设为0即可,更新fail的时候也要这么做。这样做KMP即可求出答案。

    Code

     1 #include<iostream>
     2 #include<string>
     3 #include<algorithm>
     4 #include<cstdio>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<ctime>
     8 #include<cmath>
     9 using namespace std;  
    10 
    11 const int ONE=10001;
    12 
    13 int T,C;
    14 int n,m;
    15 int a[ONE],b[ONE];
    16 int da[ONE],db[ONE],la[ONE],lb[ONE];
    17 int fail[ONE],j;
    18 int Ans[ONE],ans_num;
    19  
    20 int get()
    21 {    
    22         int res=1,Q=1;char c;
    23         while( (c=getchar())<48 || c>57 )
    24         if(c=='-')Q=-1;
    25         res=c-48;
    26         while( (c=getchar())>=48 && c<=57 )
    27         res=res*10+c-48;
    28         return res*Q;
    29 }
    30 
    31 int Da(int i,int len) {if(da[i]>=len) return 0;return da[i];}
    32 int Db(int i,int len) {if(db[i]>=len) return 0;return db[i];}
    33 
    34 int main()
    35 {
    36         T=get();    C=get();
    37         while(T--)
    38         {
    39             n=get();    m=get();
    40             memset(la,0,sizeof(la));    memset(lb,0,sizeof(lb));
    41             for(int i=1;i<=n;i++) a[i]=get();
    42             for(int i=1;i<=m;i++) b[i]=get();
    43             
    44             for(int i=1;i<=n;i++) da[i]=i-la[a[i]], la[a[i]]=i;
    45             for(int i=1;i<=m;i++) db[i]=i-lb[b[i]], lb[b[i]]=i;
    46             
    47             j=0;
    48             for(int i=2;i<=m;i++)
    49             {
    50                 j=fail[i-1];
    51                 while(j && Db(j+1,j+1)!=Db(i,j+1)) j=fail[j];
    52                 if(Db(j+1,j+1) == Db(i,j+1)) j++; else j=0;
    53                 fail[i] = j;
    54             }
    55             
    56             j=0;    ans_num=0;
    57             for(int i=1;i<=n;i++)
    58             {
    59                 while(j && Db(j+1,j+1)!=Da(i,j+1)) j=fail[j];
    60                 if(Db(j+1,j+1) == Da(i,j+1)) j++; else j=0;
    61                 if(j==m) Ans[++ans_num] = i-m+1, j=fail[j];
    62                 
    63             }
    64             
    65             printf("%d
    ",ans_num);
    66             for(int i=1;i<=ans_num;i++)
    67                 printf("%d ",Ans[i]);
    68             printf("
    ");
    69         }
    70 }
    View Code
  • 相关阅读:
    CSS简单的四种引入方式
    html之表单标签
    html基础标签之head和body标签
    Python之协程的实现
    Python之实现不同版本线程池
    Python多进程之multiprocessing模块和进程池的实现
    Python之queue模块
    sqlserver 时间格式化
    关于sql server 代理(已禁用代理xp)解决办法
    sqlserver如何启动数据库邮件
  • 原文地址:https://www.cnblogs.com/BearChild/p/6492448.html
Copyright © 2020-2023  润新知