POJ 2752

KMP中的next起到了至关重要的作用,在本题中,就是对于KMP这一核心构件的理解

说穿了,KMP中next数组一个很巧妙的地方在于不要在同一个地方跌倒两次

但是对于这道题,如果直接使用next是不符合提议的,单纯使用next会导致我们丢失一部分解(测试样例里面的aaaaa就是个好例子),因此,对于此题我的想法是另开一个数组来记录。

KMP的next我利用kn记录,kn仍然有效,因为事实上在构件KMP所需的数组时,本身就是一个递归应用KMP思想的过程,kn的存在会加速我们的迭代构建过程

#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <stack>
#include <cstdio>
#include <cstring>
using namespace std;

const int maxl= 4e5+6;

char s[maxl]; 
int l, ans[maxl], n[maxl], kn[maxl];

void PreKmp(char *x, int l, int *n)
{
	int i= 0, j= -1;

	while (i< l){
		while (j> -1 && x[i]!= x[j]){
			j= kn[j];
		}
		++i;
		++j;

		n[i]= j;
		kn[i]= x[i]== x[j] ? kn[j] : j;
	}
}

int main(int argc, char const *argv[])
{
	while (~scanf("%s\n", s)){
		memset(kn, -1, sizeof(kn));
		memset(n, -1, sizeof(n));
		memset(ans, 0, sizeof(ans));
		l= strlen(s);
		PreKmp(s, l, n);

		int i= l, j= 0;
		while (i> 0){
			ans[j++]= i;
			i= n[i];
		}

		while (j> 0){
			--j;
			if (!j){
				printf("%d", ans[j]);
			}
			else{
				printf("%d ", ans[j]);
			}
		}
		putchar('\n');
	}	
	return 0;
}
posted @ 2021-03-26 11:03  IdiotNe  阅读(24)  评论(0编辑  收藏  举报