1.11学习总结kmp算法1

学了一整天的kmp终于感觉看懂了皮毛,赶紧屁颠屁颠的来总结了:

这个算法一看就很高级,是由三位大能发现的,让搜索字串从暴力一个个回溯搜变成了用next数组来搜,本来想上一个题的,嗯,突然发现自己好像一时半会还没想明白,所以先总结一下关于自己的kmp理解:(弄了快一天了也才只会这些TAT)

先上部分代码

void getnext(char p[],int next[])//用小串来求
{
    int len2=strlen(p);
    next[0]=-1;
    int k=-1;
    int j=0;
    while(j

(这还是没you化的代码) 

这里模拟大概都会,主要是为什么要这么搞这个代码:我来浅浅地讲一下自己的想法:

我们平时都是暴力搜索子串,(这个暴力法的代码我就不给了)但是,每一次都会让子串不停的回溯到零(如果不匹配)特别是在万一很多都匹配只是是最后一个不符合的时候,就会功亏一篑,就很伤心,因为我们都已经遍历过那里了,对此我们就有了这个代码,而这个代码就是可以让我们减少很多步骤而直接精简比较如:在abcdabc里面找aba我们画图来看,

1.11学习总结kmp算法1_第1张图片

如果是暴力搜索的话,那肯定就会把子串中计数的回溯到零,然后重新开始比ab 

1.11学习总结kmp算法1_第2张图片

1.11学习总结kmp算法1_第3张图片

 但是如果用这个kmp的话就可以省下很多步骤从而节约时间,第二个图,可能这里看不出很大,但是越长重复的前后缀越多就越能看得出,不太会举例,还是等明天拿题目再来一起画一下。 

而这个next数组就是求它的前后缀的公共部分,在哪里结束就在那里站起来,我来说一个生动形象的例子,我去买东西,买了一个好看的洋娃娃,但是呢这洋娃娃的衣服和娃娃是要单独买的,突然有一天我把洋娃娃的娃娃弄丢了,但是衣服还在,所以我肯定只要买娃娃就行了,还买衣服干嘛呢,就像是一个字符串很长,然后我要找另一个字符串,它最前面和最后面有相同的部分,我搜到这一串字符和的第一轮比较最有一个和母串里的不一样,所以我没必要再重新开始子串,然后再把母串从刚开始的地方往后移一位,因为刚刚的都已经比完了,可以保证对不上我们只需要从最前缀的后面开始,然后依次往下,也就是kmp的思路了,但是这里还没完全弄明白代码TAT。

至于那个next数组就是用来求前后缀的重复的也就是我现在标记字串的位置之前的前后缀重合长度,当然,至于为什么它这个数组所求的长度恰好又对应了有关的位置那是由于我们是从零开始数的,然后前缀的最后一个字符位置就刚好是长度减一然后前面的又都是之前比完的,所以,要往这个基础上再加1正好就对应了。真的很巧妙!而这个next数组的求法也和kmp的思路差不多,时候不早了,又水了一篇文。明天上题目模拟一下。

你可能感兴趣的:(c小菜,学习)