码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 2752 Seek the Name, Seek the Fame KMP题解

时间:2014-08-12 17:16:54      阅读:237      评论:0      收藏:0      [点我收藏+]

标签:io   for   ar   html   amp   htm   size   res   

本题是KMP的next数组的灵活运用。

具体就是看最后整个数列的最后一个字母,能有多少前缀。

理解了next数组就很容易了。

#include <stdio.h>
#include <string.h>
#include <vector>
using std::vector;

const int MAX_N = 400001;
char name[MAX_N];
int next[MAX_N], len;

void genNext()
{
	for (int i = 1, j = 0; i < len; )
	{
		if (name[i] == name[j]) next[i++] = ++j;
		else if (j > 0) j = next[j-1];
		else i++;
	}
}

void getPreSuf(vector<int> &rs)
{
	rs.clear();
	int i = len;
	while (i > 0)
	{
		rs.push_back(i);
		i = next[i-1];
	}
}

int main()
{
	vector<int> rs;
	while (gets(name))
	{
		len = strlen(name);
		memset(next, 0, sizeof(int)*len);
		genNext();
		getPreSuf(rs);
		for (int i = (int)rs.size()-1; i >= 0; i--)
		{
			printf("%d ", rs[i]);
		}
		putchar('\n');
	}
	return 0;
}

要使嫌保存结果麻烦,也可以直接递归打印出来,不需要保存中间结果了:

#include <stdio.h>
#include <string.h>

const int MAX_N = 400001;
char name[MAX_N];
int next[MAX_N], len;

void genNext()
{
	for (int i = 1, j = 0; i < len; )
	{
		if (name[i] == name[j]) next[i++] = ++j;
		else if (j > 0) j = next[j-1];
		else i++;
	}
}

void printPreSuf(int i)
{
	if (i > 0)
	{
		printPreSuf(next[i-1]);
		printf("%d ", i);
	}
}

int main()
{
	while (gets(name))
	{
		len = strlen(name);
		memset(next, 0, sizeof(int)*len);
		genNext();
		printPreSuf(len);
		putchar('\n');
	}
	return 0;
}



POJ 2752 Seek the Name, Seek the Fame KMP题解,布布扣,bubuko.com

POJ 2752 Seek the Name, Seek the Fame KMP题解

标签:io   for   ar   html   amp   htm   size   res   

原文地址:http://blog.csdn.net/kenden23/article/details/38516367

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!