Example Portal: caioj1177
KMP Template: Whether the substring appears
"Test Instructions"
there are two strings of SA and sb,sa that are female strings, and SB is a substring, asking if a substring of SB has appeared in the parent string SA.
output "NO" if the start and end position of the first occurrence of the output has occurred
"Input File"
First line SA (1<= length <=1000000)
second line SB (1<= length <=1000)
"Output File"
output "NO" if SB appears in SA in the start and end position of the first occurrence of the output
"Sample 1 Input"
Aaaaabaa
AaB
"Sample 1 Output"
4 6
"Sample 2 Input"
Aaaaabaa
Aax
"Sample 2 Output"
NO
Algorithm Analysis:
KMP is actually a lazy way to first give an inheritable value by accessing a position that has been traversed before, and then violence (Khan ...). )
First, define a p array, p[i]=j, representing the SA string [1...J] and the substring formed by the SA string [i-j+1...i] exactly the same
So how do we come up with this P-array?
is violence + lazy!!! (In fact, it has been said, embarrassing)
When we access the point of I, we first visit i-1, because when we access to I have already 1~i-1 the P array, then look at the following figure:
We set J=P[I-1],I-1-J+1=I-J, then we can know sa[1...j]=sa[i-j...i-1], that is, the red zone, that if sa[j+1]=sa[i], we can directly p[i]=j+1, right?
But the reality is brutal (AC not so easy ~), then when Sa[j+1]!=sa[i] what to do? Then we'll find p[j]!!!.
We set a variable k=p[j], because P[J] is defined, so we can get SA[1...K]=SA[J-K+1...J], that is, the first two brown bands, then because two red bands are the same, so we can get sa[1...k]=sa[i-j ... I-j+k-1], the first and third brown areas
And then get Sa[j-k+1...j]=sa[i-k (i-1-k+1) ... i-1], which is the second and fourth brown intervals equal, and then!!! We get four of the brown bands equal!!! We can judge whether sa[k+1] and sa[i] are equal to seek p[i], if equal, p[i]=k+1,
Otherwise continue to find p[k]. have been looking for, until found not to find is the current p[p[p[p[p[p[.... The value is 0 o'clock, then we judge Sa[1] and Sa[i] is the same, the same p[i]=1, otherwise p[i]=0
In fact, it is not violence, but the use of the definition of the P array to find the front can be used to inherit the point!!
But here, I haven't finished KMP's study yet.
Our P array only handles the SA string, which is the substring in the title.
So how does the P array help us to ask for answers?
We set J to the suffix of the i-1 position in SB string, the longest common length of the prefix starting with the 1 position in the SA string, i.e. sa[1...j]=sb[i-j (i-1-j+1) ... j-1], then we can judge Sa[j+1] and Sb[i] is equal, the value of J is recorded, and the p[j]!!! is not equal. is not the familiar step, yes! is to transfer SB's I to the SA to solve, so that is all KMP!
Reference code:
#include <cstdio>#include<cstring>using namespacestd;Charsa[1110000],sb[1100];//SA is a parent string, SB is a substringintp[1100];//The p array is prepared for the substring, and the meaning of P is not related to the parent string. //P[i] means that the first character in SB is the end, and the maximum number of characters to be pulled forward (suffix at the end of Sb[i]) can match the prefix of SB exactly.//For example sb= "Abcdabc" in p[7]=3, so, I when you understand the meaning of p[i]intMain () {intlena,lenb,i,j; scanf ("%s", sa+1); Lena=strlen (sa+1); scanf ("%s", sb+1); Lenb=strlen (sb+1); //Manufacturing P Arraysp[1]=0; for(i=2; i<=lenb;i++) {J=p[i-1];//first record p[i-1] while(j>0&&sb[i]!=sb[j+1]) j=P[j]; /*Here are two cases if the character of the position of the j+1 is equal to the character of the I position, then directly put the p[i]=j+1 or the P value of J, because 1~sb[p[j]] must be the suffix of 1~sb[j]*/ if(sb[i]==sb[j+1]) p[i]=j+1;Elsep[i]=0; } intst,ed; J=0; for(i=1; i<=lena;i++)//followed by a P array to match the parent string { while(j>0&&sa[i]!=sb[j+1]) j=P[j]; if(sa[i]==sb[j+1]) J + +; if(J==LENB) {ed=i;st=i-lenb+1; Break;}//the beginning and the end are recorded when you get the answer . } if(J==LENB) printf ("%d%d\n", st,ed); Elseprintf"no\n"); return 0;}
Introduction to Algorithms ———— KMP