0001 void buildSS(char* P, int m, int* ss) { //O(m = |P|) 0002 ss[m-1] = m; //确定末字符对应的项;以下,自后向前地扫描P,依次计算出其余各项 0003 for (int a = m-2, b = m-2, d = 1, j = m-2; j >= 0; j--) //d = m-b-1, (a,b] = (a+d,m) 0004 if (ss[j+d] < j-a) //情况一:虽自然有[j-ss[j+d],j] = [j+d-ss[j+d],j+d] 0005 ss[j] = ss[j+d]; //但[j+d-ss[j+d]] <> [m-1-ss[j+d]],故ss[j] <= ss[j+d] 0006 else { //情况二:已有(a,j] = (a+d,j+d],MS[j]的左边界还有可能进一步拓展 0007 a = min(a,j); b = j; d = m-b-1; //更新(a,b]与d 0008 while ((0 <= a) && (P[a] == P[a+d])) //逐个比对,向左拓展(a,b] 0009 a--; //所有的while循环均由a控制,而a全程从m-2到0单调递减,故累计仅O(m) 0010 ss[j] = b-a; //MS[j] = 拓展之后的(a,b] 0011 } //else 0012 } //buildSS