bf算法:
char a[]="acabaabaabcacaabc";
char b[]="abaabcac";
思路就是从主串的第一个字符和模式串的第一个字符开始,依次比较,我们设 i 表示a数组的每个元素的下标,j 表示b数组的每个元素的下标。一开始,i=0;j=0;当碰到比较的两个字符不相等时,即i=1,j=1时,主串则跳到上次起点开始比较的字符的后面一位,即跳到a[i-j+1],而模式串则还是跳到第一个字符,即b[0],然后再依次比较.......当 j==lenb-1时,发现也匹配,那么则代表匹配成功。
下面是代码:
//BF--字符串匹配问题
#include<stdio.h>
#include<string.h>
int main(){
char a[]="acabaabaabcacaabc";
char b[]="abaabcac";
int lengtha=strlen(a);
int lengthb=strlen(b);
int i=0,j=0;
while(i<=lengtha-1 && j<=lengthb-1){
if(a[i]==b[j]){
i++;
j++;
}
else{
i=i-j+1;
j=0;
}
}
if(j>=lengthb){
printf("找到了\n");
printf("在第 %d 个位置开始",i-j+1);//i-j只是回到了最开始比较的地方,还要再加1是因为位置比下标多1.
}
else{
printf("没找到");
}
return 0;
}
kmp算法:
关键就在于求next数组。
先看代码:
int i=1,j=0;
next[1]=0;
while(i<T.length){
if( j==0 || T.ch[i]==T.ch[j] )
{
i++;j++;
next[i]=j;
}else{
j=next[j];
}
}
这个是书上给的代码,首先依据这个代码自己模拟几遍,逻辑就是如果 j 等于0 或者发现b数组有相等元素时,就让i指针和j指针加1,否则的话j=next[j];
问题就在于这句代码要怎么理解,当发现两元素不相等时,j要退到哪里,为什么是j=next[j];??
下面是举例分析:(图为转载)
假设1234567的字符和9101112131415字符相等即得到next[16]=8; (i=16;j=8) 依据上面的代码,我们下一步要做的是比较8和16字符是否相等,如果相等,则就得到next[17]=9; 如果不相等,那么j=next[8]=4;此时,123和567字符是一样的,又 1234567的字符和9101112131415字符相等 ,所以123和131415字符相等,那我们只要比较4和16字符是否相等,如果相等,则next[17]=5;如果不相等,则继续j=next[4].........
如果在写代码的时候,模拟数组从下标为0开始,那么代码为:
int len=strlen(b);
int i=0,j=-1;
next[0]=-1;
while(i<len-1){
if(j==-1||b[i]==b[j]){
i++;
j++;
next[i]=j;
}
else{
j=next[j];
}
}
下面是完整代码: