Question: Find the number of times the mode string appears in the main string [overlapped]
Sample Input
3
BAPC
BAPC
AZA
AZAZAZA
VERDI
AVERDXIVYERDIAN
Sample Output
1
3
0
Explain the magic in the Code:
The meaning of 3 can be expressed
It can be seen that next [len2] indicates the longest matching length of the prefix and suffix.
Now we can simulate the strings in this mode:
Main string: A B C A B
Mode string: A B C A B
The next step after successful matching should be:
Main string: A B C A B
Mode string: A B C A B
The pointer moves directly to the red part for matching.
How can this problem be understood?
We can see that the maximum prefix [the longest matching length of the prefix and suffix] is directly moved to the maximum suffix without looking at the last two characters A and B. Why? Because none of the above can be matched successfully.
Try to move one digit forward:
Main string: A B C A B
Mode string: A B C A B
We will not look at the last two characters A and B. We can see that the current four-length prefix is compared with the four-length suffix, obviously not
It can be matched, because the maximum length of the match is 3 [the longest length of the prefix and suffix], it is obviously not feasible to move forward.
For the first long article, if you have any errors or do not understand them, please point out
C ++ code
# Include <iostream>
# Include <fstream>
# Include <algorithm>
# Include <string>
# Include <set>
// # Include <map>
# Include <queue>
# Include <utility>
# Include <stack>
# Include <list>
# Include <vector>
# Include <cstdio>
# Include <cstdlib>
# Include <cstring>
# Include <cmath>
# Include <ctime>
# Include <ctype. h>
Using namespace std;
# Define L1 1000005
# Define L2. 10005
Int len1, len2, next [L2], res;
Char s [L1], p [L2];
Void get_next ()
{
Int k =-1, j = 0;
Next [0] =-1;
While (j <len2) // You must export next [len2]
{
If (k =-1 | p [k] = p [j])
{
J ++, k ++;
If (p [k]! = P [j])
Next [j] = k;
Else next [j] = next [k];
}
Else k = next [k];
}
/* For (j = 0; j <= len2; j ++)
Cout <next [j] <;
Cout <endl ;*/
}
Void kmp ()
{
Int I = 0, j = 0;
While (I <len1 & j <len2)
{
If (j =-1 | s [I] = p [j])
I ++, j ++;
Else j = next [j];
If (j> = len2)
Res ++, j = next [j]; // use next [len2] to greatly improve efficiency.
}
}
Int main ()
{
Int t;
Scanf ("% d", & t );
While (t --)
{
Scanf ("% s", p, s );
Len1 = strlen (s );
Len2 = strlen (p );
Res = 0;
Get_next ();
Kmp ();
Printf ("% d", res );
}
Return 0;
}