在数据结构课程中我们学习的BF算法和KMP算法都是忽略0位置,从1位置开始的。这就给我们带来了很多麻烦,在标准输入流中都是从零位置开始输入的,所以需要改进一下BF算法,使其从0位置开始比较。
下面是书本上从1位置开始的BF算法:
int Index_BF(SString S,SString T,int pos){
int j=1;
int i=pos; //初始化i,j.
while(i<=S.length&&j<=T.length){ //如果两个指针都小于各自的长度,则进入循环
if(S.ch[i]==T.ch[j]){//若当前位置相等就各自向后移动一位
i++;
j++;
}
else{ //若不相等则回溯
i=i-j+2; //先将主串回溯的本次开始匹配的下一个位置
j=1; 模式串回到1
}
}
if(j>T.length){ //判断,如果模式串指针大于字符数组的长度那么就说明匹配成功
printf("OK");
return i-T.length; //返回位置
}
else{
printf("NO");
return 0;
}
}
需要注意的是这里的length是字符串的长度,是从1开始计数的,也就是说输入字符串为“asd”,位置分别为于1,2,3位置上,长度为3,所以length=3。是忽略了0位置的长度,最后一个字符的下标为3.
也可以发现,while循环是判断条件是<=,这是因为length的作为下标的话,当他为最大值的时候是字符串的最后一个字符,这与下面的改进算法是不同的。
改进之后的算法如下:
bool Index_BF(Elemtype S,Elemtype T){
int i=0;
int j=0; //初始化i,j
while(i<S.length&&j<T.length){
if(S.data[i]==T.data[j]){
i++;
j++;
}
else{
i=i-j+1; //目标标串向后移动一位
j=0; //模式串回到起始位置
}
}
if(j>=T.length)
return true;
else
return false;
}
这里需要注意,改进之后的字符串是从0开始的,并且他的length是字符串算上0的长度,也就是“asd”,长度为3,但是他从0开始,所以最后一个字符的下标是2。
也可以看到while循环的判断条件都变成了<,因为长度length位置下标的超过字符串的。
两个算法的不同之处:
1、i,j的初始值不同,新算法是从0开始的(i的初始值可以不为0,可以定义)
2、wile循环的判断条件不同,新算法是<,因为从0开始算的话,length发生改变,下标为length的值是超出字符串的。
3、目标串回溯方式不同,新算法为i=i-j+1,老算法为i=i-j+2;因为新算法是从0开始的。
4、判断是否匹配的条件不同:新算法是j>=T.length,因为while循环中的判断条件是<,当j=的时候已经跳出了。
新改进的算法也可以查从1开始的字符串,只需要改变j的初始值为1,length为必须包含0位置,即length指向是字符串的下一个位置。同理,也可以查从2,3。。。位置开始的字符串,只需要改变j的初始值为对应的值和length是指向字符串下一个位置即可。