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;
} 
posted @ 2022-08-03 17:03  Faker_yu  阅读(41)  评论(0)    收藏  举报