KMP algorithm example + summary

I didn't learn KMP before, and then there was another question in the qualifying round to test this knowledge point. This question has AC in a row, and I am one...

KMP algorithm: establish a next function, so that the time complexity of string matching is changed from O(n*n) to O(n+m).

for example:

ababcab and abbbcabdc

First create the next array, next[0] = -1

   ababcab

-10012012 is the next array

It's very simple.....emmmmmmm, in fact, I don't know much about it, it's a bit troublesome, I don't know how to go to station B to look through the video to see


example:

String or something, my favorite

Time Limit: 2000/1000ms (Java/Others)

Problem Description:

For a string, you can add characters after, how to add the least characters to make the string become a prefix cycle at least twice.

Input:

Enter a T on the first line. A total of T groups of data
Enter a string on the second line, ( 3 <= length <= 100000 ).

Output:

Minimum number of characters to add, one line per output.

hint:
qweqwe just loops twice, so add 0
qweqe is not doubled, so add 5 and the character is qweqe. .
ababa has two loops, but the third is incomplete, so the number of additions is 1.

Sample Input:

3
aaa
abca
abcde

Sample Output:

0
2
5


AC's standard program code (with analysis):

// 1 The question requires that given a string, we need to add a few characters to form a string consisting of n loops.
// 2 It can be seen that we should first find the length of the smallest loop section of the string: assuming the length of the string is len, then the smallest loop section is cir = len-next[len] ; if there is len%cir == 0, Then this string is already a perfect string without adding any characters; if it is not perfect, the number of characters that need to be added is cir - (len-(len/cir)*cir)), which is equivalent to needing to be in the last loop Add a few more to the section above.
// 3 如果cir = 1,说明字符串只有一种字符例如“aaa” ; 如果cir = m说明最小的循环节长度为m,那么至少还需m个;如果m%cir == 0,说明已经不用添加了
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define N 100010

char s[N];
int nextval[N];
int len;

void getnext(const char *s)
{
	int i = 0, j = -1;
	nextval[0] = -1;
	while(i != len)
	{
		if(j == -1 || s[i] == s[j])
			nextval[++i] = ++j;
		else
			j = nextval[j];
	}
}

int main()
{
	int ncase;
	int length, add;
	scanf("%d", &ncase);
	while(ncase--)
	{
		scanf("%s", s);
		len = strlen(s);
		getnext(s);
/*		for(int i = 0; i <= len; ++i) //查看next数组的内容
			cout<<nextval[i]<<" ";
		cout<<endl;
		length = len - nextval[len]; //循环节的长度
		cout << length <<endl;*/
		if(len != length && len % length == 0) //循环多次
			printf("0\n");
		else
		{
			add = length - nextval[len] % length; //取余的作用:abcab,去掉abc
			printf("%d\n",add);
		}
	}
	return 0;
}


附上个博客:http://www.cnblogs.com/jackge/archive/2013/01/05/2846006.html  我就是看这个博客懂的这题

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325583250&siteId=291194637