暴力构造:
for (unsigned int j = 0; j < m; j++) gs[j] = m; //初始化
for (ui j = 0; j < m; j++)
if (ss[j] == j + 1)
for (ui i = 0; i < m - j - 1; i++)
gs[i] = min(gs[i], m - j - 1);
else
gs[m - ss[j] - 1] = min(gs[m - ss[j] - 1], m - j - 1);
for (ui i = 0; i < m; i++)
cout << gs[i] << " ";
先对ss[j] == j + 1
的情况处理,注意到:j↑,m-j-1↓
。因此,赋值区间不断缩小,且赋的新值必小于原值。
for (unsigned int j = 0; j < m; j++)
gs[j] = m; //初始化
for (ui j = m - 1, i = 0; j < UINT_MAX; j--)
if (ss[j] == j + 1)
for (; i < m - j - 1; i++)
gs[i] = m - j - 1;
for (ui j = 0; j < m - 1; j++)
if (ss[j] != j + 1)
gs[m - ss[j] - 1] = min(gs[m - ss[j] - 1], m - j - 1);
再对ss[j] != j + 1
的情况处理,注意到:gs的原值中,gs[i < m - j - 1] = m - j - 1 > i
,因此,gs[i] > i
。而ss[j] < j + 1,m - ss[j] - 1 > m - j - 2
,即m - j - 1 <= m - ss[j] - 1 < gs[m - ss[j] - 1]
。故min(gs[m - ss[j] - 1], m - j - 1) = m - j - 1
。并且,即便ss[j] == j + 1
,也不过是等价于上面的gs[i = m - j - 2] = m - j - 1
。因此可优化为:
for (unsigned int j = 0; j < m; j++) gs[j] = m; //初始化
for (unsigned int i = 0, j = m - 1; j < UINT_MAX; j--) //逆向逐一扫描各字符P[j]
if (j + 1 == ss[j]) //若P[0, j] = P[m - j - 1, m),则
while (i < m - j - 1) //对于P[m - j - 1]左侧的每个字符P[i]而言(二重循环?)
gs[i++] = m - j - 1; //m - j - 1都是gs[i]的一种选择
for (unsigned int j = 0; j < m - 1; j++) //画家算法:正向扫描P[]各字符,gs[j]不断递减,直至最小
gs[m - ss[j] - 1] = m - j - 1; //m - j - 1必是其gs[m - ss[j] - 1]值的一种选择