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 我就是看这个博客懂的这题