KMP-(HDU1358)Period[前缀中的周期]

  • KMP-(HDU1358)Period


给个传送门复习下KMP:串的模式匹配算法-KMP算法

  • 思路:

给定Next[i],Next[i]指向的总是上一循环节后面的一个字符所以上一循环节末尾为Next[i]-1

当前循环节的末尾为i-1,易得当前循环节长度:(i-1)-(Next[i]-1)=i-Next[i]

由题意已经假设0~i-1的串是循环的,所以要判断循环是否成立,只要满足长度 i 是当前循环节长度的倍数

即:i%(Next[i]-1)==0同时必须在Next[i]!=0 前提下(不重复的串Next数组中很多0)

 

  • 总结:

 对于Next数组,满足  i % ( i - Next[i] ) == 0 && Next[i] != 0 说明找到当前循环节

循环节长度:i-Next[i]

循环次数:i/(i-Next[i])

  • 代码:

#include<iostream>	
#include<cstring>	
using namespace std;
//HDU1358  Period
#define MAXSIZE 1000005
int Next[MAXSIZE];
char Str[MAXSIZE];
int Len;

void KMP()
{
	int j = -1, k = 0;
	Next[0] = -1;
	while (k < Len)
	{
		if (j == -1 || Str[j] == Str[k])
		{
			j++;
			k++;
			Next[k] = j;    //j==Next[k]
			if (k % (k - j) == 0 && j != 0)
			{
				cout << k << " " << k / (k - j) << endl;
			}
		}
		else
			j = Next[j];
	}
}

int main()
{
	int Case = 0;
	while (cin >> Len && Len)
	{

		cin >> Str;
		cout << "Test case #" << ++Case << endl;
		KMP();
		cout << endl;
	}
	return 0;
}
  • 参考:

Jack Ge for ACM-        KMP算法 —— next 数组的应用 --- 前缀中最小循环节,最大重复次数

他山之石,我之师,共勉

猜你喜欢

转载自blog.csdn.net/SZU_Crayon/article/details/81414570