The essence of the KMP algorithm is the next array, which must fully understand the next array.
NEXT[J] means the maximum number of prefixes and suffixes that can be self-matched in a true prefix of J, equivalent to a mismatch
Can eliminate a lot of unnecessary matching process.
Construct next array with recursion:
void Get_next (int *p) {int t;t = next[0] = -1;int J = 0;while (J < m) {if (T < 0 | | p[j] = = P[t]) {//Match J + +, T++;nex T[J] = t;} else//mismatch t = Next[t];}}
But there will be a lot of unnecessary matches in the next match.
For example 0 0 0 0 0 0 0 1 text string and 0 0 0 1 This pattern string, in the alignment position
0 0 0 0 0 0 0 1
0 0 0 1 under, each time the next array pattern string is moved only one lattice, essentially because there is no application
Mismatch in the case of the same character must also mismatch this rule, so we modify the next array, the NEXT[J] represents
The prefix and suffix of the true prefix of J that are capable of self-matching and the end character of the prefix and the end of the suffix are not
With, this is the extension KMP, let's use the above text string and pattern string, in the alignment position
0 0 0 0 0 0 0 1
0 0 0 1 when a mismatch is issued, the pattern string is moved directly to
0 0 0 0 0 0 0 1
0 0 0 1, this avoids many unnecessary matches.
It is easy to see that the smaller the size of the character set, the more obvious the advantages of extending KMP.
The code in the original next array can be extended by simply changing one line KMP
void Get_next (int *p) {int t;t = next[0] = -1;int J = 0;while (J < m) {if (T < 0 | | p[j] = = P[t]) {//Match J + +, T++;nex T[J] = (p[j]! = p[t]? T:next[t]);} else//mismatch t = Next[t];}}
Then the main algorithm that returns the first matching position is obvious.
int KMP () {get_next (P); int i = 0, j = 0;while (I < n && J < m) {if (J < 0 | | T[i] = = P[j]) {i++, j + +;} else {j = next[j];} if (j = = m) {return i-j+1;}} return-1;}
HDU 1711: Click to open link
The bare kmp, borrow the above code directly:
#include <cstring> #include <iostream> #include <cstdio> #include <algorithm> #include < Vector> #include <cmath>using namespace std; #define MAXN 1111111int P[MAXN], T[maxn];int N, m; #define Next Nextin T next[maxn];void get_next (int *p) {int t;t = next[0] = -1;int J = 0;while (J < m) {if (T < 0 | | p[j] = = P[t]) {//Horse With J + +, t++;next[j] = (p[j]! = p[t]? T:next[t]);} else//mismatch t = Next[t];}} int KMP () {get_next (P); int i = 0, j = 0;while (I < n && J < m) {if (J < 0 | | T[i] = = P[j]) {i++, j + +;} else {j = next[j];} if (j = = m) {return i-j+1;}} return-1;} int main () {int cas;cin >> cas;while (cas--) {scanf ("%d%d", &n, &m), for (int i = 0; i < n; i++) scanf ( "%d", &t[i]), for (int i = 0; i < m; i++) scanf ("%d", &p[i]);p rintf ("%d\n", KMP ());} return 0;}
KMP Study Notes