KMP算法核心
next函数:
1.定义:
next[k] =
1) k = 1时,next[k] = 0;
2) = max( k | { 1 < k < j ) { p[1...k-1] = p[j-k+1...j-1] }
3) 其他情况 next[k] = 1
2.递推求解
1) 定义,next[1] = 0, 假设next[j] = k, p[1..k-1] = p[j-k+1..j-1]
2) 若p[j] = p[k], p[1..k] = p[j-k+1..j], next[j+1] = next[j] + 1 = k + 1;
3) 若p[j] != p[k],匹配失败时 k = next[j];
View Code
#include<stdio.h> #include<string.h> #include<stdlib.h> int next[10000]; int nextval[10000]; //求next函数 /* 1.next[1] = 0; 2.'p1..pk-1' = 'pj-k+1..pj-1' 3.pj = pk next[j+1] = next[j] + 1; pj != pk 此时把求next函数看作一个模式匹配问题,整个模式串既是主串 又是模式串。 */ void get_next(char *st) { next[1] = 0; int i = 1, j = 0; int len = strlen(st + 1); while( i <= len ) { if( st[i] == st[j] || j == 0 ) { i++, j++; next[i] = j; } else j = next[j]; } } /* next函数优化版 * / void get_nextval(char *st ) { int i = 1, j = 0; nextval[1] = 0; int len = strlen( st + 1); while( i <= len ) { if( j == 0 || st[i] == st[j] ) { i++, j++; if( st[i] != st[j] ) nextval[i] = j; else nextval[i] = nextval[j]; } else j = nextval[j]; } } /* 在匹配过程中产生失配: 1. 指针i不变,指针j退回到next[j]所指示的位置上进行比较。 2. 当指针j退至0时, 指针i, 指针j都需要同时加1 */ int Index_KMP(char *str, char *st, int pos ) { int i = pos, j = 1; int len1 = strlen(str+1); int len2 = strlen(st+1); while( i <= len1 && j <= len2 ) { if( str[i] == st[j] || j == 0 ) { ++i, ++j; } else j = next[j]; } if( j > len2 ) { return i - len2; } else return 0; } int main( ) { char str[10000]; char st[100]; while( scanf("%s%s", str + 1,st + 1) != EOF ) { memset(next, 0, sizeof(next)); printf("%s\n%s\n",str+1, st+1); get_next( st ); printf("%d\n", Index_KMP(str, st, 1)); } return 0; }