String children make a lot of good friends, most of them are very helpful, help the string solve his problem
A. String hash
Strings eager to make friends with integers, a hash is a medium between a connection string and an integer, and he can match a string and an integer to each other. What is the hash? Of course, this is to do the problem of the person himself to set.
The formula for finding a string prefix hash is: hash "i" = (1ll *hash "I-1" *p+idx (S "i"))%mod;
where P itself is set to a six-bit or eight-bit prime, MoD takes 1e9+7 or +9,idx (s[i]) =s[i]-' a '
Now let's talk about how to ask for a substring hash, the formula is: Hash[l ... R]= ((hash[r]-hash[l-1]* (R-l+1 of P))%mod+mod)%mod
Several commonly used strings hashing: 1 unsigned long long hash[n] hash[i]=hash[i-1]* automatic modulo
2 Tanhashi
3 double hash, which represents a string with pair
Application of hashing:
1 S1 is not a S2 substring, and in the S2 appeared several times
2 Finding the largest common substring of S1 and S2
3 Find the longest palindrome string in a string
4 Representation of minimum dictionary order after a series of operations
The hash code is as follows:
//use a single hash to denote a string prefix//and Judge S1 a few times in S2.voidHashbuild (intN1,intn2) { for(intI=1; i<=n1;i++) {Hash1[i]= (1ll*hash1[i-1]*p+s1[i]='a')%MoD; } for(intI=1; i<=n2;i++) {Hash2[i]= (1ll*hash2[i-1]*p+s2[i]-'a')%MoD; } for(intI=1; i<=n2;i++) {Fp[i]=Pow (p,i); } for(inti=n1;i<=n2;i++){ if((Hash2[i]-1ll*hash2[i-n1]*fp[n1]%mod+mod)%mod==hash[n1]) ans++; }}hash1
//use a single hash to denote a string prefix//and Judge S1 a few times in S2.voidHashbuild (intN1,intn2) { for(intI=1; i<=n1;i++) {Hash1[i]= (1ll*hash1[i-1]*p+s1[i]='a')%MoD; } for(intI=1; i<=n2;i++) {Hash2[i]= (1ll*hash2[i-1]*p+s2[i]-'a')%MoD; } for(intI=1; i<=n2;i++) {Fp[i]=Pow (p,i); } for(inti=n1;i<=n2;i++){ if((Hash2[i]-1ll*hash2[i-n1]*fp[i]%mod+mod)%mod==hash[n1]) ans++
Two. KMP algorithm
To see if S1 is S2 's substring.
Next is the same part of the prefix suffix the maximum value
Next:aaa
Position 0 1 2
J= 1 2 3
Next-1 0 1
Notice the first I-1, and don't count yourself
Next value means: The same prefix suffix that represents the length of the string that precedes the current character. For example, if Next [j] = k, the string representing the preceding J has the same prefix suffix with the maximum length K .
KMP algorithm
Assuming that the text string s is now matched to the I position, the pattern string P matches to the J position
- If j =-1, or if the current character matches successfully (ie s[i] = = P[j]), make i++,j++ continue to match the next character;
- If J! =-1, and the current character match fails (that is, s[i]! = P[j]), then I is unchanged, j = next[j]. This means that when mismatch occurs, the pattern string p moves the J-next [j] bit to the right relative to the text string s.
//an optimized next array method voidGetnextval (Char* p,intnext[]) { intPlen =strlen (P); next[0] = -1; intK =-1; intj =0; while(J < Plen-1) { //P[k] Represents a prefix, p[j] represents a suffix if(k = =-1|| P[J] = =P[k]) { ++J; ++K; //compared to the previous next array, the change is in the following 4 lines if(P[j]! =P[k]) next[j]= k;//only this line before Else //because the p[j] = p[Next[j]] is not present, so you need to continue recursion when it appears, k = next[k] = next[next[k]]NEXT[J] =Next[k]; } Else{k=Next[k]; } } }
The return value is where S1 appears in S2
intKmpsearch (Char* S,Char*p) {inti =0; intj =0; intSlen =strlen (s); intPlen =strlen (P); while(I < Slen && J <Plen) { //① If J =-1, or if the current character match succeeds (ie s[i] = = P[j]), the i++,j++ if(j = =-1|| S[i] = =P[j]) {i++; J++; } Else { //② If J! =-1, and the current character match fails (that is, s[i]! = P[j]), then I is unchanged, j = Next[j]//Next[j] is the next value corresponding to Jj =Next[j]; } } if(J = =Plen)returnIj+1; Else return-1; }
The small partner of the string