【模拟7.25】匹配

作为考试第一题,难度比较小,开始时忘记KMP打法,于是先做第二题了,迅速水完第二题

回来想了想,其实单论数据范围hash明显可解甚至更快

KMP时间复杂度O(n+m)即两个字符串长度

hash该题中复杂度O(n).........

没啥可说的

hash:

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 #include<algorithm>
  6 #include<cmath>
  7 #include<stack>
  8 #include<map>
  9 #include<queue>
 10 #define ps push_back
 11 #define MAXN 205101
 12 #define ll unsigned long long
 13 using namespace std;
 14 int T;
 15 ll hash_A,hash_B,hash_AA,hash_BB;
 16 int la,lb;
 17 ll base=131ll;
 18 ll base1=1ll;
 19 char a[MAXN],b[MAXN];
 20 char c;
 21 ll bass,bass1;
 22 int main()
 23 {
 24    scanf("%d",&T);
 25    while(T--)
 26    {
 27        scanf("%d%d",&la,&lb);
 28        if(lb<=10000)
 29        {
 30         scanf("%s",a+1);
 31         base=131;
 32         base1=1;
 33         hash_A=0;hash_B=0;
 34         for(int i=1;i<=lb;++i)
 35         {
 36             b[i]=a[i];
 37         }
 38         cin>>c;
 39         lb++;
 40         b[lb]=c;
 41         int kx=0;
 42         int ans=0;
 43         for(int i=lb;i>=1;--i)
 44         {
 45             kx++;
 46             hash_A=(hash_A*base)+(a[kx]-'a'+1);
 47             hash_B=(b[i]-'a'+1)*base1+hash_B;
 48             base1*=base;  
 49             //printf("i=%d ",i);
 50             //cout<<a[kx]<<b[i]<<endl;
 51             //printf("hase_A=%lld B=%lld\n",hash_A,hash_B);
 52             if(hash_A==hash_B)
 53             {
 54                 ans=kx;
 55             }
 56         }
 57         printf("%d\n",ans);
 58         base=131;
 59         base1=1;
 60         hash_A=0;hash_B=0;
 61       }
 62       else
 63       {
 64         scanf("%s",a+1);
 65         base=131;bass=1331;
 66         base1=1;bass1=1;
 67         hash_A=hash_B=hash_AA=hash_BB=0;
 68         for(int i=1;i<=lb;++i)
 69         {
 70             b[i]=a[i];
 71         }
 72         cin>>c;
 73         lb++;
 74         b[lb]=c;
 75         int kx=0;
 76         int ans=0;
 77         for(int i=lb;i>=1;--i)
 78         {
 79              kx++;
 80              hash_A=(hash_A*base)+(a[kx]-'a'+1);
 81              hash_B=(b[i]-'a'+1)*base1+hash_B;
 82             
 83              hash_AA=(hash_AA*bass)+(a[kx]-'a'+1);
 84              hash_BB=(b[i]-'a'+1)*bass1+hash_BB;
 85             
 86              base1*=base; 
 87              bass1*=bass; 
 88             //printf("i=%d ",i);
 89             //cout<<a[kx]<<b[i]<<endl;
 90             //printf("hase_A=%lld B=%lld\n",hash_AA,hash_BB);
 91              if(hash_A==hash_B&&hash_AA==hash_BB)
 92              {
 93                  ans=kx;
 94              }
 95         }
 96         printf("%d\n",ans);
 97         base=131;bass=1331;
 98         base1=1;bass1=1;
 99         hash_A=hash_B=hash_AA=hash_BB=0; 
100       }
101    }
102 }
103 /*
104 2
105 5 3
106 adabc
107 d
108 */
View Code

(为了防数据卡我,我还打了双hash,好像没啥必要......)

KMP:

考后复习了一下

首先next数组 next[i]表示该字符串以i结尾的最长后缀==前缀的长度

定义指针j=0从i=2开始移动(由定义可知next[1]=0)

然后while(j!=0&&a[j+1]!=a[i])j=next[j];

应用了next数组的性质,若是当前的字符和指针的下一个字符不匹配就向前移动

(由next数组定义可知,这样移动正确)

然后求解f数组相似不再细说

(其实暴力的字符串用hash都能过.......)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<stack>
 8 #include<map>
 9 #include<queue>
10 #define ps push_back
11 #define MAXN 205101
12 #define ll unsigned long long
13 using namespace std;
14 int T;
15 int la,lb;
16 char a[MAXN],b[MAXN];
17 int nxt[MAXN],f[MAXN];
18 char c;
19 int main()
20 {
21    scanf("%d",&T);
22    while(T--)
23    {
24        memset(nxt,0,sizeof(nxt));
25        memset(f,0,sizeof(f));
26        scanf("%d%d",&la,&lb);
27        scanf("%s",a+1);
28        for(int i=1;i<=lb;++i)
29        {
30            b[i]=a[i];
31        }
32        cin>>c;
33        lb++;
34        b[lb]=c;
35        nxt[1]=0;
36        for(int i=2,j=0;i<=la;++i)
37        {
38            while(j>0&&a[i]!=a[j+1])j=nxt[j];
39            if(a[i]==a[j+1])j++;
40            
41            nxt[i]=j;
42        }
43        for(int i=1,j=0;i<=lb;++i)
44        {
45            while(j>0&&(j==la||b[i]!=a[j+1]))
46            {
47            //printf("j=%d\n",j);
48            j=nxt[j];}
49            if(b[i]==a[j+1])j++;
50            
51            f[i]=j;//printf("i=%d %d\n",i,f[i]);
52        }
53        printf("%d\n",f[lb]);
54   }
55 }
56 /*
57 2
58 5 3
59 adabc
60 d
61 */
View Code

 

posted @ 2019-07-26 08:04  Wwb_star  阅读(116)  评论(0编辑  收藏  举报