給定模式串 b 和文本串 a,求 b 在 a 中出現的次數(可重疊)。經典 KMP 匹配問題。
b 計算 next 數組,記錄每個前綴的最長真前綴兼真後綴長度。i(文本)、j(模式)同步推進;失配時根據 next[j] 回退 j,i 不回退,保證 O(n+m) 複雜度。j == b_len,計數器加一,並令 j = next[j] 繼續尋找下一次匹配(允許重疊)。
void GetLCPS() {
int j = 0, k = -1;
int len = strlen(b);
next[0] = -1;
while (j < len) {
if (k == -1 || b[k] == b[j]) next[++j] = ++k;
else k = next[k];
}
}
void KMP() {
int i = 0, j = 0, ans = 0;
int a_len = strlen(a), b_len = strlen(b);
while (i < a_len) {
if (j == -1 || a[i] == b[j]) { ++i; ++j; }
else j = next[j];
if (j == b_len) { ++ans; j = next[j]; }
}
printf("%d\n", ans);
}
預處理 O(m),匹配 O(n),總時間 O(n+m),空間 O(m)。適合長文本(10^6)與多測試用例場景。
scanf("%s") 讀取非空白字符串。