一、BP暴力匹配
目的:串Aabcdef
,查出Bef
在串A最初出现的位置
#include <stdio.h>
#include <string.h>
#include <math.h>
void main()
{
char a[]="abcabcdef";
char b[]="abcdef";
int i,j,flag;
for(i=0;i<strlen(a)-strlen(b)+1;i++){
flag=0;
for(j=0;j<strlen(b);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
由来: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 <stdio.h>
#include <string.h>
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<strlen(b))
{
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<strlen(b); 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++的影响
}
}
}