字符串匹配算法我们先了解BF算法,对我们理解KMP算法有帮助
目录
1.BF算法
此时,i与j不想等了,字串重新从下标0开始,主串回到B的位置,因为比的过程中,主串与字串前进的长度一样,那么,i-j就找到了主串开始的位置,+1就到后面的元素,从i-j+1这里重新开始与字串比较
整个过程我们清楚了
具体函数细节:
当两个串都为空,则警告。
一个串为空,直接判断不存在的-1
主串走完,字串没走完,肯定返回-1
字串走完,那如果此时j的大小大于等于字串长度那就找到了,返回主串中起始位置。
#include<stdio.h>
#include<assert.h>
//str表示主串
//sub表示字串
//返回值:返回字串在主串当中的下标,如果不存在则返回-1
int BF(char *str,char* sub)
{
assert(str!=NULL&&sub!=NULL)
if(str==NULL||sub==NULL)
{
return -1
}
int lenSTR=strlen(str);
int lenSUB=strlen(sub);
int i=0;
int j=0;
while(i<lenSTR&&j<lenSUB)
{
if(str[i)==sub[j])
{ i++;
j++;
}
else
{
i=i-j+1;
j=0;
}
}
if(j>=lenSUB)
{
return i-j;
}
return -1;
}
int main()
{
printf("%d\n",BF("ababcabcdabcde","abcd")); //5
printf("%d\n",BF("ababcabcdabcde","abcdf")); //-1
printf("%d\n",BF("ababcabcdabcde","ab")); //0
return 0;
}
2.KMP算法:
其实我们在上面BF算法也发现了,很多时候在进行一些已经算过的位置,重复比较。
但是首不能到末
根据推导过程,有:设子串为p
再有:k-1-0=i-1-x
k=i-x;
x=i-k 就有:
如果找不到p[i】==p【k】,则k=-1,k+1=0.则next【6】=0
C语言代码实现:
//str代表主串
//sub代表字串
//pos代表从主串的pos位置开始找
int KMP(char* str,char*sub int pos)
{
assert(str!=NULL&&sub!=NULL);
int lenStr=strlen(str);
int lenSub=strlen(sub);
if(lenStr==0||lenSub==0)
return -1;
if(pos<0||pos>=lenStr)
return -1;
int next*=(int*)malloc(sizeof(int)*lenSub);
assert(next!=NULL);
Getnext(sub,next,lenSub);
int i=pos;//遍历主串
int j=0;//遍历字串
while(i<lenStr&&j<lenSub)
{
if(j==-1||str[i]==sub[j])
{ i++;
j++;
}
else
{
j=next[j];
}
}
free(next);
if(j>=lenSub)
{
return i-j;
}
return -1;
}
void* Getnext(char *sub,int *next,int lenSub)
{
next[0]=-1;
next[1]=0;
int i=2;//当前i下标
int k=0;//代表前一项的k
while(i<lenSub)
{
if(i==-1||(sub[i-1]==sub[k]))
{
next[i]=k+1;
i++;
k++;
}
else{
k=next[k];
}
}
}
3.next数组优化:
next数组的优化:next_val数组
练习:
答案默认从0开始,不是从-1开始,所以所有的值都加一