克努特-莫里斯-普拉特(KMP)算法;
#include <cstdio> #include <cstring> const int N = 101; const int M = 51; char a[N], b[M]; int lena, lenb, next[M], nextval[M]; void Get_next() { int i = 0, j = -1; next[i] = j; while(i < lenb) { if(j == -1 || b[i] == b[j]) { i++; j++; next[i] = j; } else { j = next[j]; } } } void Get_nextval() //next[]的改进; { int i = 0, j = -1; nextval[i] = j; while(i < lenb) { if(j == -1 || nextval[i] == nextval[j]) { i++; j++; if(b[i] == b[j]) nextval[i]=nextval[j]; else nextval[i]=j; } else j=nextval[j]; } } int index_KMP() //适用于模式串与主串存在较多部分匹配情况下, 否则和朴素匹配差别不大, 但nextval[]数组 也是一种改进; { int i = 0, j = 0; while(i < lena && j < lenb) { if(j == -1 || a[i] == b[j]) { i++; j++; if(j == lenb) return i-j+1; } else j = next[j]; } } void LXL() // x^n 求n最大值 { if(lenb%(lenb-next[lenb])==0) printf("%d\n", lenb/(lenb-next[lenb])); else printf("1\n"); } void FindPrefix-suffiLength() //既是前缀又是后缀 输出长度 { int num[N]; Get_next(); int k = 0; for(int i = lenb; i != 0) { num[k++] = next[i]; i = next[i]; } for(int j = k-2; j >= 0; j--) printf("%d\n", num[i]); printf("%d\n", lenb); } int main(){ while(scanf("%s%s", a, b)) { lena = strlen(a); lenb = strlen(b); Get_next(); Get_nextval(); // printf("1\n"); for(int i = 0; i <= lenb; i++) printf(i==lenb?"%d\n":"%d ", next[i]); for(int i = 0; i <= lenb; i++) printf(i==lenb?"%d\n":"%d ", nextval[i]); int Q = index_KMP(); printf("%d\n", Q); FindPrefix-suffiLength(); } return 0; }
浙公网安备 33010602011771号