去了360面试,问了一个关于KMP的知识点,呀,完全忘了啊,太不应该了,然后就打算看看这个KMP,,,
看了好多关于KMP算法的书籍和资料,总感觉没有说的很清楚,为什么会产生next数组,为什么给出了那么简短的程序,没有一个过程,而有的帖子虽然next及其字符串匹配说的很清楚,但是推理的一些过程相当复杂,比较抽象,今天在这里简单的提一下我的理解,尽可能的把这个过程讲的简单,容易理解
从模式匹配之初:我们先是研究的是BF算法,鉴于我们经常行的需要回溯,总是做一些无用功,为了提高算法的时间度和空间度,引入了next数组(至于为什么提高时间,下面会提到),也就是采用next数组,我们不需要再去回溯了,可以直接比较,这也就是KMP算法了
所以说:从BF到KMP,只是简单的嫌弃BF算法,花费的时间空间太长太大了而已,一切都在进步!!!
串的模式匹配或者串匹配:
子串的定位操作是找子串在主串中从POS个字符后首次出现的位置
一般将主串S称为目标串,子串T称为模式串
BF算法:
Brute-Force,也称为蛮力(暴力)匹配算法
1,从主串S的第pos个字符开始,和模式串T的第一个字符进行比较,
2,若相等,则逐个比较后续的字符;不然,就回溯到主串的第POS+1个字符开始,继续和模式串T的第一个字符进行比较,反复执行步骤2,知道模式串T中的每一个字符都和主串相等(返回当前主串S匹配上的第一个字符)或者找完主串S(POS位置后的所有字符(返回0)),
程序1:
#include <stdio.h>
#include <string.h>
#include <malloc.h>
int BFmode(char *s, char *t, int pos)
{
int flag1,flag;
int i,j;
int slength, tlength;
slength = strlen(s);
tlength = strlen(t);
for(i = pos; i < slength; i++)
{
flag1 = i,flag = 0;
for(j = 0; j < tlength; j++)
{
if(s[i] == t[j] && i < slength)
{
flag ++;
i++;
}
else
break;
}
if(flag == tlength)
{
return flag + 1;
}
i = flag1;
}
return 0;
}
int main()
{
char s[50]; //目标串
char t[20]; //模式串同时也是子串
int pos;
scanf("%s", s);
scanf("%s", t);
scanf("%d", &pos);
pos = BFmode(s,t, pos);
printf("POS:%d\n", pos);
return 0;
}
编写完了之后,总觉得怪怪的,程序不应该这么复杂啊,
程序2:
int BFmode(char *s, char *t, int pos)
{
int flag1,flag;
int i,j = 0;
int slength, tlength;
slength = strlen(s);
tlength = strlen(t);
for(i = pos; i < slength && j < tlength; i++)
{
if(s[i] == t[j])
{
j++;
if(j == tlength)
return i - j + 2;
}
else
{
i = i - j;
j = 0;
}
}
return 0;
}
我们还可以将程序优化一下: 毕竟程序的重点是(时间和空间),
算法比较简单,但是在最坏的情况下,算法的时间复杂度为O(n×m),n,m分别为主串