KMP

太简单了
考场现推吧
就是一个 n e x t next next数组
n e x t i next_i nexti表示前缀字符串 s t [ 1... i ] st[1...i] st[1...i]存在的一个最大的前缀字符串 s t [ 1.... j ] st[1....j] st[1....j]使得 s t [ 1.... j ] = s t [ i − j + 1...... i ] st[1....j] = st[i - j + 1 ...... i] st[1....j]=st[ij+1......i]
然后就没了
code:

// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define N 1000005
using namespace std;
int a[N], nxt[N];
char st[N], st1[N];
int main(){
   scanf("%s", st + 1);
   scanf("%s", st1 + 1);
   int len1 = strlen(st + 1), len2 = strlen(st1 + 1);
   int j = 0;
   for(int i = 1; i < len2; i ++){//因为是后缀的最大前缀,所以要错开一位,从1开始循环,2开始建nxt
   	while(j && st1[j + 1] != st1[i + 1]) j = nxt[j];//匹配不到就往前跳
   	j += (st1[j + 1] == st1[i + 1]);
   	nxt[i + 1] = j;
   }
   j = 0;
   for(int i = 0; i < len1; i ++){//匹配
   	while(j && st1[j + 1] != st[i + 1]) j = nxt[j];
   	j += (st1[j + 1] == st[i + 1]);
   	if(j == len2) a[++ a[0]] = i + 1 - j + 1, j = nxt[j];
   }
   for(int i = 1; i <= a[0]; i ++) printf("%d\n", a[i]);// printf("\n");
   for(int i = 1; i <= len2; i ++) printf("%d ", nxt[i]);
   return 0;
}
posted @ 2019-08-10 08:44  lahlah  阅读(27)  评论(0编辑  收藏  举报