1 Const intN =100005;2 intWa[n],wb[n],wv[n],ws[n];3 intcmpint*r,intAintBintl)4 {5 returnr[a]==r[b]&&r[a+l]==r[b+l];6 }7 voidDaint*r,int*sa,intNintm)8 {9 inti,j,p,*x=wa,*y=WB;Ten //The following four lines are a cardinal sort of the first letter: The Cardinal sort is actually the number of positions in front of the record. One for(i=0; i<m;i++) ws[i]=0;//empties an array of statistical character numbers A for(i=0; i<n;i++) ws[x[i]=r[i]]++;//count the number of characters - for(i=1; i<m;i++) ws[i]+=ws[i-1];//make a summation, because the previous small character set has a positional contribution to the following character's row position - for(i=n-1; i>=0; i--) sa[--ws[x[i]]]=i;//Sort by position, sa[x] = I, indicating I position is at x bit the //Wa[x[i]] is the character set 0-x[i] Total number of characters occupy the position, minus one of their own position the rest is their own rankings, ranking starting from 0 - //The main process in the ranking process is to sort the characters that are in the same character, because changing the wa[x[i]] is worth only to itself, less than the contribution value of that character - //is constant, the same basis for the first character is the positional relationship, and you will see a second keyword to determine the relationship of the same character - + - //This sort of sorting is done by two keywords to determine the position of a string, that is to multiply the thought + //by splitting a string into two parts, and the position of the two parts we've all calculated A for(j=1, p=1;p <n;j*=2, m=p) at { - for(p=0, i=n-j;i<n;i++) y[p++]=i;//The enumeration string is used to merge the strings with the I position, because I is larger because the matched string is an empty string - //since the enumeration is a string of length J, then the string at the start of the I position will not be able to make up this length of string, so the second keyword should be minimal, where the position of the front of the smaller - for(i=0; i<n;i++)if(sa[i]>=j) Y[p++]=sa[i]-j;//Sa[i]-j begins with a string matching the second keyword with the number sa[i], Sa[i]<j's string is not matched as a second keyword - for(i=0; i<n;i++) Wv[i]=x[y[i]];//Remove the first keyword from these positions - for(i=0; i<m;i++) ws[i]=0; in for(i=0; i<n;i++) ws[wv[i]]++; - for(i=1; i<m;i++) ws[i]+=ws[i-1]; to for(i=n-1; i>=0; i--) Sa[--ws[wv[i]]]=y[i];//base Order of the first keyword by the second keyword + for(Swap (x, y), p=1, x[sa[0]]=0, i=1; i<n;i++)//one-time character set reduction and constant optimization for a well-ordered SA array -X[SA[I]]=CMP (y,sa[i-1],sa[i],j)? p1:p + +; the } * return; $ }Panax Notoginseng - intRank[n],height[n]; the voidCalheight (int*r,int*sa,intN//here n is the original length of the string, that is, does not include the new 0 + { A inti,j,k=0; the for(i=1; i<=n;i++) rank[sa[i]]=i;//There is a suffix array to get the rank array, the No. 0 suffix must be added 0 + for(i=0; i<n;height[rank[i++]]=k)//suffixes beginning with I are always able to inherit k-1 matches from suffixes beginning with i-1 - for(k?k--:0, j=sa[rank[i]-1];r[i+k]==r[j+k];k++);//for a violent match, but the time complexity of the entire algorithm is still O (n) $ return; $}
Suffix array template from Ro God Ben (with detailed comments)