//KMP串的模式匹配算法 #include <stdio.h> #include <stdlib.h> #include <string.h> int* get_next(char t[], int length) { int i = 0, j = -1; int* next = (int *)malloc(length * sizeof(int)); next[0] = -1; while (i < length) { if (j == -1 || t[i] == t[j]) { i++; j++; next[i] = j; } else { j = next[j]; } } return next; } int Index_KMP(char s[], char t[], int sl, int tl, int next[]) { int j, i; j = 0; i = 0; while (j < tl && i < sl) { if (j == -1 || s[i] == t[j]) { i++; j++; } else { j = next[j]; } } if (j == tl) { return i - tl; } else { return 0; } } //计算next函数修正值的算法 int *get_nextval(char t[], int length) { int i = 0, j = -1; int* nextval = (int*)malloc(length*sizeof(int)); nextval[0] = -1; while (i < length) { if (j == -1 || t[i]==t[j]) { j++; i++; if (t[j]!=t[i]) { nextval[i] = j; } else { nextval[i] = nextval[j]; //回溯到下标为nextval[j]但元素与下标为nextval[i]的元素不相同的位置 } } else { j = nextval[j]; } } return nextval; } int main() { char s[] = "acabaabaabcacaabc"; char t[] = "abaabcac"; char t2[] = "abcdabd"; int tl = strlen(t); int sl = strlen(s); /*int *next = get_next(t, tl); int c = Index_KMP(s, t, sl, tl, next); //返回开始正确匹配的下标(s的下标) printf("%d ", c);*/ int l = strlen(t2); int * nextval = get_nextval(t,tl); /*for(int i = 0; i<l;i++) { printf("%d ",nextval[i]); }*/ int c = Index_KMP(s, t, sl, tl, nextval); printf("%d ",c); printf(" "); return 0; }
理解:
模式匹配就是将主串中下标为i的元素与模式串中下标为j的元素进行比较(比较过程中i不会回溯 而j的值会按照next对应的值进行回溯)