KMP
洛谷P3375
不好说,感性理解就行,上代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n, m, nx[N];
string s, t;
int main()
{
cin >> s >> t, n = s.size(), m = t.size();
nx[0] = -1;
for(int j = 1, k = -1; j <= m; ++j) //时间复杂度分析:j只会右移m次,所以最多左跳m次
{
while(k ^ -1 && t[j - 1] ^ t[k]) k = nx[k]; //可证若下一位不匹配,nx[j]是k的border,所以一直跳nx
nx[j] = ++k; //匹配就加一位(若从上次失败-1加过来还是对的)
}
for(int i = 0, j = 0; i < n; ++i) //同理,j只会右移n次,所以最多左跳n次,O(m + n)
{
while(j ^ -1 && s[i] ^ t[j]) j = nx[j]; //利用border让i不退
++j;
if(j == m) cout << i - m + 2 << '\n';
}
for(int i = 1; i <= m; ++i) cout << nx[i] << ' ';
return 0;
}

浙公网安备 33010602011771号