目的:串Aabcdef,查出Bef在串A最初出现的位置
#include二、KMP#include #include void main() { char a[]="abcabcdef"; char b[]="abcdef"; int i,j,flag; for(i=0;i flag=0; for(j=0;j if(b[j]==a[j+i]){ flag++; }else{ break; } } if(flag==strlen(b)){ printf("下标为%d",i); break; }else if(i==strlen(a)-strlen(b)){ printf("不存在"); break; } } }
由来:KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的
案例:串Aabcdef,查出Bef在串A最初出现的位置
A工作:求出Next数组
解释:就是需要去B字符串,比较前缀(不包含最后一项)和后缀(不包含第一项),找出最大重合项长度(回溯长度),写入数组
示例:abacaca
- 它的前三项前缀a,ab后缀a,ba,最大重合项长度为1;
- 它的前五项前缀a,ab,aba,abac后缀a,ca,aca,baca,最大重合项长度为1;
B工作:调整回溯长度
特点:与bp相比只差下面那一行,要注意其放置的位置
if(flag!=0)
{
i=i+flag-next[flag]-1;//消除i++的影响
}
代码实现:
#include#include void main() { char a[]="Iacdacdbeacdacdc"; char b[]="acdacdc"; int next[strlen(b)+1];// 把list[0]留为-1,从1开始 int i=0,j=-1;// j为存储对比哪个数的下标 next[0]=-1; int flag=0;// 跳出循环标注 while(i if(j==-1||b[i]==b[j]) { j++;// 每次一次跨度最多一个 i++; next[i]=j; } else { j=next[j]; } } // 上面已经统计完next数组下标需要移动多少(值得注意的是从1开始存放的是需要的数据) // char a[]="abacde"; // char b[]="ab"; for(i=0; i<=strlen(a)-strlen(b); i++) { flag=0; for(j=0; j if(b[j]==a[j+i]) { flag++; } else { break; } } if(flag==strlen(b)) { printf("下标位%d",i); break; } else if(i==strlen(a)-strlen(b)) { printf("不存在"); break; } if(flag!=0) { i=i+flag-next[flag]-1;//消除i++的影响 } } }


![C语言数据结构[字符串匹配][BP、KMP] C语言数据结构[字符串匹配][BP、KMP]](http://www.mshxw.com/aiimages/31/968841.png)
