//: KMP
// The KMP algorithm is the most efficient pattern matching algorithm.
// The main idea is: (Suppose I, J point to the current matching position of the Main string mstr and the mode SSTR respectively) When mstr [I]! = Mstr [J] is not
// Repeat the traditional backtracking I, j, But I does not change J and returns an array backtracking. This array enables the pattern string to the right.
// Move as many distances as possible.
// Main principle: assume that when I and j do not match, the key character of the mode should be compared with the J character of the Main string.
// Then: SSTR [1 ~ K-1] = mstr [I-k + 1 ~ I-1
// Also known: SSTR [J-k + 1 ~ J-1] = mstr [I-k + 1 ~ I-1
// So: SSTR [1 ~ K-1] = SSTR [J-k + 1 ~ J-1];
// Therefore, the maximum K corresponding to each character can be calculated based on the string and stored in next []. The simple method is as follows:
// 1, initialize next [0] =-1, I, j Represents SSTR [0 ~ I-1] = SSTR [j-i-1, J-1] I, j and J + 1 is the current mismatch position
// 2. If SSTR [I] = SSTR [J]; then SSTR [0 ~ I] = SSTR [j-i-1, J], if SSTR [0 ~ I + 1] = SSTR [j-i-1, J + 1]
// When the J + 1 position is not matched, the push to the I + 1 position will also be mismatched, therefore, set next [J + 1] = next [I + 1] If SSTR [0 ~ I + 1]! = SSTR [j-i-1, J + 1]
// Next [J + 1] = I + 1;
// 3. If j <strlen (SSTR) repeats 2
// 4, exit
# Include <iostream>
# Include <cstdio>
Int * getindex (const char * pstr, int * Next) // match the array with a timely String Pattern
{
Next [0] =-1, next [1] = 0;
Int I = 0, j = 1;
While (j <strlen (pstr ))
{
If (I =-1 | pstr [I] = pstr [J])
{
// If I =-1, the first character of the mode is compared with the next character of the Main string.
// If pstr [I] = pstr [J] compares subsequent characters
++ I, ++ J;
If (pstr [I] = pstr [J])
{// SSTR [0 ~ I] = SSTR [j-i-1, J]
Next [J] = next [I];
}
Else
{// SSTR [0 ~ I]! = SSTR [j-i-1, J]
Next [J] = I;
}
}
Else
{
I = next [I];
}
}
Return next;
}
Int KMP (const char * mainsour, const char * substr, int POS)
{
Int res =-1;
Int * Next = new int [strlen (substr)];
// Calculate the Array
Getindex (substr, next );
Int I = POs, j = 0, end = strlen (substr );
While (I <End) // does not reach the end of the main string
{
If (mainsour [I] = substr [J] | j =-1)
{
++ I, ++ J;
If (! Substr [J])
{
Res = I-strlen (substr );
Break;
}
}
Else
{// Backend J if the mismatch exists
J = next [J];
}
}
Return res;
}
Int main ()
{
STD: cout <KMP ("ababcabcacbab", "abcac", 0) <STD: Endl;
Return 0;
}