今天上数据结构的时候,老师讲了一下KMP,之前也接触过,记一下KMP的思想。参考了一些博客,等一下附上。
匹配两个字符串的时候,每次当失配的时候,都移动F串一位。所以时间复杂度是O(n*m);
但是当我匹配到I的时候,我忽略了前面的都已经匹配好了这个事实,利用起来。多移动一些K,K有什么特点呢?
例如:
直接要跳到最后一步。
这时:模式串每一个字符都记录这个失配指针,直接跳到这里,那么KMP很好写了。
void find(char *T,char *P,int *f) { int n = strlen(T); int m = strlen(P); getFail(P,f); /* for(int i=0;i<m;i++) printf("%d ",f[i]); puts(""); */ int j = 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 ",i-m+1); } }
那么,怎么得到next数组这个失配指针呢?
重点来了,就是模式串自己匹配自己。
根据f[0],f[1],...,f[i-1] 推 f[i];
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]; if(P[i]==P[j]) f[i+1] = j+1; else f[i+1] = 0; } }
f[0] = 0,f[1] = 0;
开始推f[2] ,也就是要匹配P[0],和P[1],匹配好了就是等于1,否则是0,
再往后走,就是类似之前的两个字符串的匹配了,不相等的时候就直接跳到 f[j] 进行匹配,直到匹配好。
参考:http://blog.csdn.net/yutianzuijin/article/details/11954939/