boolsingle_match(int* ps, int up, int low){ if (up == low) return ps[-up] == *ps; if (up) { if (*ps >= ps[-up]) returnfalse; } if (low) { if (*ps <= ps[-low]) returnfalse; } returntrue; } /************* ps => the pointer to the current matching position up, low => the matching limit, indicating the relative position of the character to be compared ps[-low] < *ps, *ps < ps[-up] special cases: up == 0 => no upper limit low == 0 => no lower limit up == low => ps[-low] == *ps, *ps == ps[-up] *************/
int last_pos[K] = {}; for (int i = 1; i <= m; ++i) { if (last_pos[s[i]]) { up[i] = low[i] = i - last_pos[s[i]]; } else { int upx = s[i]; for (; upx < K && !last_pos[upx]; ++upx) continue; if (upx == K) up[i] = 0; else up[i] = i - last_pos[upx];
int lowx = s[i]; for (; lowx >= 0 && !last_pos[lowx]; --lowx) continue; if (lowx == -1) low[i] = 0; else low[i] = i - last_pos[lowx]; }
last_pos[s[i]] = i; }
next[0] = next[1] = 0; for (int i = 2, j = 0; i <= m; ++i) { for (; j > 0 && !single_match (s + i, up[j + 1], low[j + 1]); j = next[j]) continue; next[i] = ++j; } }