KMP算法
在我刚刚接触KMP算法时,因为看的是学校的数据结构教材,写的十分繁杂,可读性极差,网上找了一些教程视屏基本上一看就会了,下面介绍我学习KMP算法的一些心得。
1.KMP算法的核心就是构建基于从串创建的next数组
代码如下
void Build_next(char *str)//建立next数列
{
next[0]=0;
int len=strlen(str);
int i=0,j=1,m=0;
while(next[len-1]==NULL&&len>1)
{
if(str[i]==str[j])
{
next[j]=i+1;
i++;
j++;
}
else if(str[i]!=str[j]&&i==0)
{
next[j]=0;
j++;
}
else
{
i=next[i-1];
}
}
}
- 代码解读
next数组就是看你当前所在串位置之前串的最大前缀与后缀相同的字符个数,
举个例子str="aabaa********"*
前缀分别为a ,aa,aab,aaba,后缀分别为,a,aa,baa,abaa,可以看出最大相同前缀为aa,所以在第五个字符处next[4]=2;
依次类推求出next数组的所有值;
- 这里要特别注意求next数组并没有想象的那么简单
1.设置 i=0,j=1;分别指向字符串的第一和第二个字母
2.上面代码中while循环中:
1️⃣第一个判断条件1:如果str[i]==str[j] 那么next[j]=i+1; i++;j++;
2️⃣第二个判断条件2: 如果str[i]!=str[j]且str[i]在首位置 那么next[j]=0;j++;
3️⃣ 第三个判断条件3:关键条件,如果如果str[i]!=str[j]且str[i]不在在首位置 ,那么i=next[i-1];然后再进行比较,直到循环结束。
2.根据next数组进行串匹配。
代码如下:
int Arg_KMP(int next[],char *main_str,char *sub_str)//KMP算法
{
int i=0,j=0,time=0;
int len_main=strlen(main_str);
int len_sub=strlen(sub_str);
if(len_main<len_sub) //从串大于主串退出
{
printf("从串大于主串 错误!");
return 0;
}
while(i<=len_main-1)
{
if(main_str[i]==sub_str[j])
{
i++;
j++;
}
else if(main_str[i]!=sub_str[j]&&j!=0)
{
j=next[j-1];
}
else
{
i++;
}
if(j==len_sub-1)
{
time++;
j=0;
}
}
return time;
}
- 代码解读
1.注意从串小于主串
2.while循环和next循环判断条件类似,但是需要注意 这里的i,j ,一个在主串 一个在从串上,且都是从0开始的。