p数组记录的是当该位置上失配的时候,跳到第几个进行继续匹配;
 1 /*
 2    题意:给两个数串,求模板串第一此出现在源串中的位置,开头的位置;没有输出-1;
 3    算法:kmp
 4    先对字符串进行自匹配;
 5    然后串间匹配;
 6  */
 7 #include<iostream>
 8 #include<cstdio>
 9 #include<cstring>
10 #include<string>
11 using namespace std;
12 int s[1000005],t[10005],p[10005];//s是源串,t是模板串,p是自匹配数组(next);
13 int n,m;
14 int kmp()//模板;
15 {
16     int ans=0;
17     p[0]=p[1]=0;
18     //p数组是错位排列的,p[i]表示的是p[i-1]的信息;即到目前为止的最长前缀;
19     for(int i=1;i<m;i++)
20     {
21         int j=p[i];
22         while(j&&t[i]!=t[j])
23         {
24             j=p[j];//定位j的位置;
25         }
26         p[i+1]=t[i]==t[j]?j+1:0;
27     }
28     int j=0,temp=0;
29     for(int i=0;i<n;i++)
30     {
31         while(j&&s[i]!=t[j])
32         {
33             j=p[j];
34         }
35         if(s[i]==t[j])
36             j++;
37         if(j==m)
38             return i+1-m+1;
39     }
40     return 0;
41     //可以判断是否有子串,也可以计算有多少子串;
42 }
43 int main()
44 {
45     int T;
46     scanf("%d",&T);
47     while(T--)
48     {
49         memset(s,0,sizeof(s));
50         memset(t,0,sizeof(t));
51         scanf("%d%d",&n,&m);
52         for(int i=0;i<n;i++)
53             scanf("%d",&s[i]);
54         for(int i=0;i<m;i++)
55         {
56             scanf("%d",&t[i]);
57         }
58         int ans=kmp();
59         if(ans==0)
60             printf("-1\n");
61         else
62             printf("%d\n",ans);
63     }
64     return 0;
65 }
View Code

相关文章:

  • 2021-08-24
  • 2021-07-24
  • 2021-11-22
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-06-18
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-01-09
  • 2022-12-23
  • 2021-10-04
  • 2021-11-15
相关资源
相似解决方案