KMP题目重在理解next数组的含义:
next数组的作用 :next[j] 记录模式串中第 j 个字符的最长公共前缀长度(重要,这是它的意义所在)
next[len] (即字符串'\0'结束标志的next值):单个字符串匹配时与周期有关
HDU 1711(模板题) 3336 1358 2203 2594 3746
HDU 1711
#include <string.h>
#include <iostream>
using namespace std;
int a[1000005],b[10005];
int p[10005];
int n,m;
void getNext () {
int i,j = 0;
p[1] = 0;
for (i = 2; i <= m; i++) {
while (j > 0 && b[j+1] != b[i]) {
j = p[j];
}
if (b[i] == b[j+1]) j++;
p[i] = j;
}
}
void kmp () {
int i,j = 0;
for (i = 1; i <= n; i++) {
while (j > 0 && b[j+1] != a[i]) {
j = p[j];
}
if (b[j+1] == a[i]) j++;
if (j == m) {
printf("%d\n",i - m +1 );
return ;
}
}
printf("%d\n",-1);
}
int main () {
int t;
scanf("%d",&t);
while (t--) {
scanf("%d%d",&n,&m);
int i,j;
for (i = 1; i <= n ;i++) scanf("%d",&a[i]);
for (i = 1; i <= m; i++) scanf("%d",&b[i]);
getNext();
kmp();
}
return 0;
}
HDU 3746
#include <stdio.h>
#include <string.h>
#define LEN 1000001
int next[LEN];
int len;
char str[LEN];
void getNext() {
int i, j;
next[0] = -1;
i = 0;
j = -1;
while(str[i] != '\0') {
if(-1 == j || str[i] == str[j]) {
++i;
++j;
next[i] = j;
}
else {
j = next[j];
}
}
}
int main() {
int files;
scanf("%d", &files);
while(files--) {
int period;
scanf("%s", str);
memset(next, 0, sizeof(next));
getNext();
len = strlen(str);
period = len - next[len];
if(next[len] == 0) {
printf("%d\n", len);
}
else if(len%period == 0) {
printf("0\n");
}
else {
int ans = period - (len%period);
printf("%d\n", ans);
}
}
return 0;
}