kmp字符串匹配原理参考博客:https://blog.csdn.net/bqw18744018044/article/details/90516750
代码如下:(写一遍模板)
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef unsigned int ui; 4 typedef long long ll; 5 typedef unsigned long long ull; 6 #define pf printf 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 #define prime1 1e9+7 9 #define prime2 1e9+9 10 #define pi 3.14159265 11 #define lson l,mid,rt<<1 12 #define rson mid+1,r,rt<<1|1 13 #define scand(x) scanf("%llf",&x) 14 #define f(i,a,b) for(int i=a;i<=b;i++) 15 #define scan(a) scanf("%d",&a) 16 #define dbg(args) cout<<#args<<":"<<args<<endl; 17 #define inf 0x3f3f3f3f 18 #define maxn 1000010 19 int n,m,t; 20 int nxt[maxn];//nxt数组:i位置失配后nxt[i]就是下一个该匹配的字符 21 char s[maxn],p[maxn];//主串和模式串 22 void getnxt() 23 { 24 int plen=strlen(p); 25 int i=-1,j=0; 26 nxt[0]=-1; 27 while(j<plen) 28 { 29 if(i==-1||p[i]==p[j]) 30 { 31 i++,j++; 32 if(p[i]!=p[j])nxt[j]=i;//如果两者相等则在失配情况下转到i位置之后照样会失配 33 else nxt[j]=nxt[i]; 34 } 35 else i=nxt[i];//失配后在前的i指针继续寻找匹配项 36 } 37 } 38 int kmp(char *s,char *p) 39 { 40 int slen=strlen(s); 41 int plen=strlen(p); 42 int cnt=0; 43 int i=0,j=0; 44 while(i<slen) 45 { 46 if(j==-1||s[i]==p[j])i++,j++;//j==-1的时候说明s[i]这一位是不可能正确匹配的 47 else j=nxt[j]; 48 if(j==plen)cnt++; 49 } 50 return cnt; 51 } 52 int main() 53 { 54 //freopen("input.txt","r",stdin); 55 //freopen("output.txt","w",stdout); 56 std::ios::sync_with_stdio(false); 57 scan(t); 58 while(t--) 59 { 60 scanf("%s %s",p,s); 61 getnxt(); 62 pf("%d\n",kmp(s,p)); 63 } 64 }