KMP: n + 1 times Probe

As you can see, this is I do not know how many times to learn the KMP.
Recommended topic string UESTC the B station.

Introduction: KMP is doing

KMP is solved pattern string P the number of occurrences in the source string T problem, such as a pattern string P ABA, the source string is ABABABA, we can find the number of occurrences to calculate the overlap 3, it may also be determined without calculating the number of overlap 2.

next array

  • [x] is best not to use an array named next next, some will complain OJ
Front (rear) (post) and the true prefix conjugation:! Time before a string s i (i <= strlen (s)) for the prefix character, i = strlen (s) is true prefixes, suffixes, and with the proper suffix management.

[I] expressed in the pattern string P i is the end of this prefix, the longest common prefix and suffix is ​​the true length of the next, e.g. abcabc, next [1: 6] = {0,0,0,1,2,3}

Seeking next array

Suppose we already know the next [1: i-1], seeking next [i].

Set last = next [i-1], the p [1: last] is equal to p [i-last: i-1], i.e., the pattern string of length i-1 prefix, before the last one the same as the last one, and last maximum, then we only need to detect p [i] and p [last + 1] are equal, equal is the last + 1, otherwise they will be in these last months (p [i-last: i-1], that is p [1 : last]) inside to find updated last = next [last], continues to detect the p [i] and p [last + 1] are equal, and so on until the last = 0, p [i] = p [1], namely 1, and 0 otherwise.

Then only need to set the next [1] = 0, to find the cycle.

The real KMP

By calculating the next array, we find: the role of the array is the next face of the current match well, but not when the next match, a smaller update to match, instead of re-matching to speed up match.

KMP process and procedure of finding the next almost identical.

We set to match to the number of last T [i-1] is already the current match, i.e., when the last = strlen (P), the match is successful, and now find the matching last T [i] at.

We have already matched last months, p [1: last] equal to t [i-last: i-1] (is not very familiar with), if p [i] and t [+ 1 last] the same, last ++, otherwise jump to the front, last = next [last], the attempt to match the smaller, until it is completely not match.

Code

Action: How many times the output matching, may overlap.

Since the ordinary input starts from 0, the next code array from 0 to n-1, each less than a normal next array.

Back to the beginning of the problem, if you want to find a match does not overlap the back every time to match, last = 0 can be.

#include<bits/stdc++.h>
using namespace std;
int n,last;
char t[1000020],p[1002000];
int nex[1002000];
int main(){
    scanf("%d",&n);
    while(n--){
        int ans=0;
        scanf("%s%s",p,t);
        int pl=strlen(p),tl=strlen(t);
        nex[0]=last=-1;
        for(int i=1;i<pl;i++){
            while(last>-1&&p[i]!=p[last+1]){
                last=nex[last];
            }
            if(p[i]==p[last+1]){
                last++;
            }
            nex[i]=last;
        }
        last=-1;
        for(int i=0;i<tl;i++){
            while(last>-1&&t[i]!=p[last+1]){
                last=nex[last];
            }
            if(t[i]==p[last+1]) last++; 
            if(last+1==pl){
                ans++;
                last=nex[last];
                //printf("%d\n",i-pl+2);
            }
        }
        /*for(int i=0;i<pl;i++){
            //if(i!=0) printf(" "); 
            //printf("%d",nex[i]);
        }*/
        printf("%d\n",ans);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/sz-wcc/p/11331357.html