The problem of string matching improves efficiency by introducing next []
The next [] array is constructed based on the features of the pattern string;
The next [] array is introduced to determine the position of J when the next matching fails. The value of next [J] indicates P [0... j-1] the length of the longest suffix is equal to the prefix of the same character sequence.
During the matching process, if no match occurs, if next [J]> = 0, the pointer I of the target string remains unchanged, move the pointer J of the mode string to the position of next [J] to continue matching. If next [J] =-1, move I to the right of 1 and set J to 0, continue the comparison.
Specific ideas:
Next [0] =-1, assuming next [J] = K, that is, P [0... k-1] = P [J-K, J-1]
1) if p [J] = P [K], p [0 .. k] = P [J-K, J]. Obviously, next [J + 1] = next [J] + 1 = k + 1;
2) If P [J]! = P [K], we can regard it as a pattern matching problem, that is, how to move the K value when the matching fails. Obviously, K = next [K].
Template:
Next [];
Void getnext (char * P, int * Next) {Int J, K; next [0] =-1; j = 0; k =-1; while (j <strlen (P)-1) {If (k =-1 | P [J] = P [k]) // when matching, P [J] = P [k] {J ++; k ++; next [J] = K;} else // P [J]! = P [k] K = next [k] ;}}
Match string;
Int kmp_search (char const * SRC, int slen, char const * patn, int Plen, int const * nextval, int POS)
{
Int I = Pos;
Int J = 0;
While (I <slen & J <Plen)
{
If (j =-1 | SRC [I] = patn [J])
{
++ I;
++ J;
}
Else
{
J = nextval [J];
// When the matching fails, use P [j_next] to compare it with s [I,
// The following describes how to calculate this value, that is, the location of the next matching after the matching fails.
}
}
If (j> = Plen)
Return I-plen;
Else
Return-1;
}
Hangdian 1711
This is a complicated code:
# Include <string>
# Include <iostream>
# Include <cstdio>
# Include <cstring>
Using namespace STD;
Int SRC [1000501], PRN [15001];
Int nextval [15001];
Template <typename S, typename T>
Void get_nextval (s const * ptrn, t Plen, T * nextval)
{
Int I = 0; // note, which is different from the code below: I starts from 0 (code implementation 2: I starts from 1)
Nextval [I] =-1;
Int J =-1;
While (I <plen-1)
{
If (j =-1 | ptrn [I] = ptrn [J]) // if part of the loop
{
++ I;
++ J;
// The following four rows occur in the corrected location:
If (ptrn [I]! = Ptrn [J]) // + I, ++ J, judge the relationship between ptrn [I] And ptrn [J] Again
Nextval [I] = J; // The previous error solution lies in that this sentence is the only one in the entire judgment.
Else
Nextval [I] = nextval [J];
}
Else // loop else Section
J = nextval [J];
}
}
Template <typename S, typename T>
Int kmp_search (s const * SRC, t slen, s const * patn, t Plen, t const * nextval, t POS)
{
T I = Pos;
T j = 0;
While (I <slen & J <Plen)
{
If (j =-1 | SRC [I] = patn [J])
{
++ I;
++ J;
}
Else
{
J = nextval [J];
// When the matching fails, use P [j_next] to compare it with s [I,
// The following describes how to calculate this value, that is, the location of the next matching after the matching fails.
}
}
If (j> = Plen)
Return I-plen + 1;
Else
Return-1;
}
Int main ()
{
Int T, slen, Plen, I, j,;
Scanf ("% d", & T );
While (t --)
{
Scanf ("% d", & slen, & Plen );
For (I = 0; I <slen; I ++)
Scanf ("% d", SRC + I );
For (j = 0; j <Plen; j ++)
Scanf ("% d", PRN + J );
Get_nextval (PRN, Plen, nextval );
A = kmp_search (SRC, slen, PRN, Plen, nextval, 0 );
Printf ("% d \ n", );
}
Return 0;
}
Hangdian 1686
# Include <string>
# Include <iostream>
# Include <cstdio>
# Include <cstring>
Using namespace STD;
Char SRC [1000500], PRN [10050];
Int nextval [10050], slen, Plen;
Void get_nextval (INT Plen)
{
Int I = 0; // note, which is different from the code below: I starts from 0 (code implementation 2: I starts from 1)
Nextval [I] =-1;
Int J =-1;
While (I <= plen-1)
{
If (j =-1 | PRN [I] = PRN [J]) // if part of the loop
{
I ++;
J ++;
// The following four rows occur in the corrected location:
// After ++ I, ++ J, judge the relationship between ptrn [I] And ptrn [J] again.
Nextval [I] = J; // The previous error solution lies in that this sentence is the only one in the entire judgment.
}
Else // loop else Section
J = nextval [J];
}
}
Int kmp_search (INT slen, int Plen)
{
Int I = 0;
Int J = 0, Count = 0;
While (I <slen)
{
If (j =-1 | SRC [I] = PRN [J])
{
I ++;
J ++;
}
Else
J = nextval [J];
If (j = Plen)
Count ++;
}
Return count;
}
Int main ()
{
Int T, I, j,;
Scanf ("% d", & T );
While (t --)
{
Scanf ("% S % s", PRN, Src );
Slen = strlen (SRC );
Plen = strlen (PRN );
Get_nextval (Plen );
A = kmp_search (slen, Plen );
Printf ("% d \ n", );
}
Return 0;
}