KMP
void find(char* T, char* P) { int n = strlen(T), m = strlen(P); getFail(P, f); int j = 0; //当前结点编号,初始为0号结点 for(int i = 0; i < n; i++) { //文本串当前指针 while(j && P[j]!=T[i]) j = f[j]; //顺着是失配边走,直到可以匹配 if(P[j] == T[i]) j++; if(j == m) printf("%d\n", i-m+1); //找到了 } }
为什么要顺着失配边走?:每次沿失配边走都是当前状态的尽可能最大值
void getFail(char* P, int* f) { int m = strlen(P); f[0] = 0; f[1] = 0; for(int i = 1; i < m; i++){ int j = f[i]; while(j && P[i]!=P[j]) j = f[j]; f[i+1] = P[i] == P[j]? j+1 : 0; } }
T:文本串
P:模式串
f[i]:P的前i长度子串中前后对称的最大长度(不含"全"(j > f[j]))

浙公网安备 33010602011771号