BF算法
字符串匹配的比较简单直观的算法
思想:两个标记元素,串从头开始匹配,中间有匹配不成功的,主串从下一个开始,子串从头开始跟主串匹配
#include <stdio.h>
#include <string.h>
typedef struct
{
char ch[100];
int length;
}SString;
int index_bf(SString S,SString T,int pos)
{
int i=pos,j=0;
while(i<=S.length&&j<T.length)
{
if(S.ch[i]==T.ch[j])
{
++i;
++j;
}
else
{
i=i-j+1;
j=0;
}
}
if(j>=T.length)
return i-T.length+1;
else
return 0;
}
int main()
{
SString S,T;
char a[100]="aaaaaaaaabaa";
char b[100]="ab";
strcpy(S.ch,a);
strcpy(T.ch,b);
S.length=12;
T.length=2;
int x=index_bf(S,T,0);
printf("%d",x);
}
KMP算法
(一)next值算法
(1)例:求串 t="abcaabbabcab"的next值
方法:先写出一行
j: 1 2 3 4 5 6 7 8 9 10 11 12
t: a b c a a b b a b c a b
next:
第一个next跟第二个肯定是0跟1。
从第三个开始往前看,串尾倒着跟串头正着进行对比。如果有相同的元素,next的值就等于相同元素加一。
j: 1 2 3 4 5 6 7 8 9 10 11 12
t: a b c a a b b a b c a b
next:0 1 1 1
第三个,串尾是b,头是a。没有相同的,就是1,第四个同理。
j: 1 2 3 4 5 6 7 8 9 10 11 12
t: a b c a a b b a b c a b
next:0 1 1 1 2 2
第五个,a跟串头a相同,所以是2,6同理。
j: 1 2 3 4 5 6 7 8 9 10 11 12
t: a b c a a b b a b c a b
next:0 1 1 1 2 2 3 1 2 3 4 5
第七个,串尾的ab跟头ab相同所以是3
同理算可出其他的。
(2)nextval算法
第一步先算出next值
j: 1 2 3 4 5 6 7 8 9 10 11 12
t: a b c a a b b a b c a b
next: 0 1 1 1 2 2 3 1 2 3 4 5
nextval:0 1 1 0
第三个开始:
1:比较t[j]与t[next[j]],就是比较这个序号对应的字母是否与这个序号对应的next对应的字母相同,例如第三个,就是比较c是否与第一个字母a相同。
2:如果相同,则这个序号对应的nextval值就是next对应的nextval值。
3:如果不同,这个序号的nextval就是这个序号的next值
第三个,不相同,所以第三个的nextval值就是1。
第四个,a与t[1]=a相同,所以它的nextva就是第一个元素的nextval 0。
实现代码(BF&KMP):
#include <stdio.h>
#include <string.h>
typedef struct
{
char ch[100];
int length;
} SString;
int index_bf(SString S,SString T,int pos)
{
int i=pos,j=0;
while(i<=S.length&&j<T.length)
{
if(S.ch[i]==T.ch[j])
{
++i;
++j;
}
else
{
i=i-j+1;
j=0;
}
}
if(j>=T.length)
return i-T.length+1;
else
return 0;
}
int Index_Kmp(SString S,SString T,int pos,int nextval[])
{
int i=pos;
int j=0;
while(i<=S.length&&j<=T.length)
{
if(j==0||S.ch[i]==T.ch[j])
{
++i;
++j;
}
else
{
j=nextval[j];
}
}
if(j>=T.length)
return i-T.length+1;
else
return 0;
}
void get_nextval(SString T,int nextval[])
{
int i=1;
nextval[1]=0;
int j=1;
while(i<T.length)
{
if(j==0||T.ch[i]==T.ch[j])
{
i++;
j++;
if(T.ch[i]!=T.ch[j])
nextval[i]=j;
else
nextval[i]=nextval[j];
}
else
j=nextval[j];
}
}
int main()
{
SString S,T;
char a[100]="aaaaaaaaabaa";
char b[100]="ab";
strcpy(S.ch,a);
strcpy(T.ch,b);
S.length=12;
T.length=2;
int x=index_bf(S,T,0);
int *nextval;
get_nextval(T,nextval);
int y=Index_Kmp(S,T,0,nextval);
printf("%d %d\n",x,y);
}