KMP算法本质上是字符串的自我匹配
朴素的单模式串匹配大概就是枚举每一个文本串元素,然后开始不断向后比较,每次比较失败之后都要从头开始重新比对,最差情况时间复杂度在O(n*m)左右,还是比较容易卡的。
而 KMP 的精髓在于,对于每次失配之后,都不会从头重新开始枚举,从前面重复的地方开始匹配,从而节约时间,时间复杂度为O(n);
主要代码:
int j=0;
for (int i = 2; i <=l2; i++)
{
while(j&&st2[i]!=st2[j+1])j=k[j];
if(st2[i]==st2[j+1])j++;
k[i]=j;
}
j=0;
for (int i = 1; i <=l1; i++)
{
while(j&&st1[i]!=st2[j+1])j=k[j];
if (st1[i]==st2[j+1])j++;
if(j==l2){
cout<<i-l2+1<<endl;
j=k[j];
}
}
再理解这个模板后,KMP也就没有其它神奇之处了,自己脑补的例子再结合网上的代码慢慢理解,再多做几个题就行。
时间取决于每个人对代码的理解力,所以几个小时都理解不了的KMP算法并不能说明自身能力不行,而是意味着在解决这个算法后,自身对代码理解能力的大幅度提升,在我攻关KMP后去学图论的一些知识,感觉也并不是很难。