自己发明的KMP,蜜汁操作和书上不太一样,过了HDU两道题,应该没错。
1 #include<bits/stdc++.h> 2 #define ll long long 3 #define scan(i) scanf("%d",&i) 4 #define scand(i) scanf("%lf",&i) 5 #define scanl(i) scanf("%lld",&i) 6 #define scans(i) scanf("%s",i) 7 #define f(i,a,b) for(int i=a;i<=b;i++) 8 #define pb(i) push_back(i) 9 #define ppb pop_back() 10 #define pf printf 11 #define dbg(args...) cout<<#args<<" : "<<args<<endl; 12 #define input freopen("in.txt","r",stdin) 13 #define output freopen("out.txt","w",stdout) 14 #define io ios::sync_with_stdio(0) 15 using namespace std; 16 int t,n; 17 const int maxn=1000005; 18 char ss1[maxn],ss2[maxn]; 19 int nxt[maxn]; 20 int nxt2[maxn]; 21 vector<int> ans; 22 void getnxt(char s[],int nxt[]){ 23 int len=strlen(s+1); 24 nxt[1]=0; 25 int p=1; 26 int k=0; 27 while(p<=len){ 28 if(k==0){ 29 nxt[p]=k; 30 p++; 31 k++; 32 } 33 else if(s[k]==s[p]){ 34 nxt[p]=k; 35 p++; 36 k++; 37 } 38 else k=nxt[k]; 39 } 40 } 41 void getnxt2(char s[],int nxt[],int nxt2[]){ 42 getnxt(s,nxt); 43 int len=strlen(s+1); 44 f(i,1,len){ 45 nxt2[i]=nxt[i-1]+1; 46 if(s[i]==nxt2[i]){ 47 nxt2[i]=nxt2[nxt2[i]]; 48 } 49 } 50 } 51 int kmp(char s1[],char s2[]){ 52 int cnt=0; 53 getnxt(s2,nxt); 54 int len1=strlen(s1+1); 55 int len2=strlen(s2+1); 56 int p1=1; 57 int p2=1; 58 while(p2<=len2){ 59 if(s1[p1]==s2[p2]){ 60 p1++; 61 p2++; 62 } 63 else{ 64 if(p1==1) p2++; 65 else p1=nxt[p1-1]+1; 66 } 67 if(p1==len1+1){ 68 cnt++; 69 nxt[len1]+1; 70 } 71 } 72 return cnt; 73 } 74 int kmp2(char s1[],char s2[]){ 75 int cnt=0; 76 getnxt2(s2,nxt,nxt2); 77 int len1=strlen(s1+1); 78 int len2=strlen(s2+1); 79 int p1=1; 80 int p2=1; 81 while(p2<=len2){ 82 if(s1[p1]==s2[p2]){ 83 p1++; 84 p2++; 85 } 86 else{ 87 if(p1==1) p2++; 88 else p1=nxt2[p1]; 89 } 90 91 if(p1==len1+1){ 92 cnt++; 93 p1=nxt[len1]+1; 94 } 95 } 96 return cnt; 97 } 98 int main(){ 99 scan(t); 100 f(i,1,t){ 101 scanf("%s",ss1+1); 102 scanf("%s",ss2+1); 103 pf("%d ",kmp(ss1,ss2)); 104 } 105 }