E6-B KMP
题目描述
这是一道 KMP 的模板题,尽管有多种方法可以通过此题,但还是建议大家利用此题测试自己的模板。
给定两个字符串 s,t(1≤∣s∣,∣t∣≤105) ,请求出$ t 在 s $中的出现次数,及每次出现开始位置(下标从 0 开始)。
输入
第一行一个正整数 T(1≤T≤5) 代表数据组数;
每组第一行一个字符串 s(1≤∣s∣≤105) ,第二行一个字符串$ t(1≤|t|≤10^5)$ ;
输出
对于每组数据输出一行:
先输出$ t 在 s$ 中的出现次数 n ,接下来输出 n 个数,代表$ t$ 在$ s $中的出现开始位置(若未出现则不输出)。
输入保证$ Σ|s|,Σ|t|≤2×10^5 $。
输入样例
1 2 3 4 5
| 2 aaabaab aab abababba aba
|
输出样例
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| #include <bits/stdc++.h> using namespace std; #define ll long long vector<int> piFunction(string s) { vector<int> pi; pi.push_back(0); int n = s.length(); for (int i = 1; i < n; i++) { int j = pi[i - 1]; while (j != 0 && s[j] != s[i]) j = pi[j - 1]; if (s[j] == s[i]) j++; pi.push_back(j); } return pi; } void kmp(string s, string t) { ll ls = s.length(); ll lt = t.length(); string cur = t + '#' + s; vector<int> pi = piFunction(cur); int ans = 0; vector<int> position; for (int i = lt + 1; i <= ls + lt; i++) { if (pi[i] == lt) { position.push_back(i - lt - lt + 1); ans++; } } cout << ans << " "; for (int i : position) cout << i << " "; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int T; cin >> T; while (T--) { string s, t; cin >> s >> t; kmp(s, t); cout << endl; }
return 0; }
|