第4章学习小结

串的模式匹配

一、BF算法 —— 暴力匹配

       1、当前匹配,++i;++j;

       2、当前不匹配,i=i-j+2;j=1;

二、KMP算法

首先是主串s 和模式串t 的比较,当前比较的是主串s的第i个和模式串的第j个,若s[i]==t[j]; 则++i; ++j; 这里i,j为位置,而非下标

当出现不匹配时,i不回溯(停留在当前位置),通过next数组找到下一个和s[i]比较的数的下标k;

由于模式串t的任一元素都有可能和s在匹配时,失配,所以要为t的每个元素找好一个“后备军”k 以应对t[j]和s[i]不匹配的情况。于是这里用next数组来存储这些"后备军“k,当s[i]!=t[j],则j退到第二选择k,再进行s[i]和s[k]的比较

明显k不是随便的一个数,作为t[j]的“后备军”,满足:k之前的k-1个数和j前的k-1个数一一相等,只有这样t[k]才能而直接和当前已和t[i]失配的s[i]比较,而免去前k-1次和s的比较

以下是关于next数组的理解

设此时j的“后备军”为k,即next[j]=k,那么要求next[j+1]的值,则需要比较t[j]和t[k]的值,即比较t[j]和t[k]

若t[j]==t[k],那么next[j+1]=next[j]+1;否则再退一步,比较t[j]和t[next[k]]直到比较到相等的,或比到最后的最后:t[j]!=t[1],则next[j]=1

void get_next(SString T, int next[])
{//求模式串T的next函数值并存入数组next
    i=1;next[1]=0;j=0;
    while(i<T.length)
    {
        if(j==0 || T.ch[i]==T.ch[j]
        {
            ++i;
            ++j;
            next[i]=j;
        }
        else
            j=next[j];
    }
}

然而,以上函数然存在缺陷,例如在面对主串为“aaabaaaab",模式串为”aaaab“时,仍浪费了时间

于是改进为

void get_next(sstring t,int Next[])  //求模式串t的next函数值并存入数组next 
{
    int i=1,j=0;
    Next[1]=0;
    while(i<t.length)
    {
        if(j==0 || t.ch[i]==t.ch[j])
        {
            ++i;
            ++j;
            if(t.ch[i]!=t.ch[j])
                Next[i]=j;
            else
                Next[i]=Next[j];
        }
        else
            j=Next[j];
    }

不同的是,若当前比较时t.ch[i]!=t.ch[j],则Next[i]的值再退一步到Next[j]的值

 

心得体会

花了很长一段时间还是被如何next数组难倒,看了很多人关于这方面的代码,还是没能理解,有的人next数组从-1开始,有的人从0开始,看来看去,整个人思维很混乱,因为一开始自己对next数组就没有理解清楚,越乱越急。后来还是回归书本,自己用一个模式串带函数进去走一遍,然后就慢慢理解的其中的关系,看来还是要有自己的理解先,实在不行就用土办法,土办法还是挺好用的 ^_^

 

关于上次确定的目标及接下来的目标

这回练习的代码数量增多了,具体实施的时候还参考了很多其他人的代码,在一道需要C语言的函数题中参考了关于C的输入输出的资料:https://www.cnblogs.com/JCSU/articles/1306308.html

接下来的目标还是多练习💪

posted @ 2019-04-14 01:08  小蔡不能菜  阅读(287)  评论(2编辑  收藏  举报