简洁明了的kmp算法

接下来我把经典的kmp算法分为两步来行动

第一步,先将模式串做好相应的标志位

核心思想:解释起来比较抽象,还不如不解释,下面我将直接结合例子来解释

第一步,先将各字符以及各字符在字符串的位置表示出来,用一个int型数组存储各个字符的下标,首先int[0]=-1(表示这是第一个字符),int[1]=0(对应字符串中地址为0的字符),如下所示:
这里写图片描述
第二步,比较S1刚刚已经确立的地址为1的字符和S2刚刚确立的地址下标为0的字符,如果两者字符相等,则表示下一个地址的字符的下标为现在地址的下标加一(如果a[1]=a[0],a[2]地址的下标就为0+1=1)反之,则直到该字符与字符下标的字符下标的。。。字符相等或字符下标等于-1,则表示下一个地址的字符的下标为现在地址的下标加一(如图,为B的a[1]不等于为A的a[0],又因为a[0]的下标为-1,则a[2]的下标为0)
这里写图片描述
接下来,按照第二步的算法规则遍历完整个字符串,就得到了如下所示字符下标的排列顺序。
这里写图片描述
接下来代码如下所示:

#define max 100
int visit[max];
void ap(str str)
    {
    int i=1;
    visit[0]=-1;
    visit[1]=0;
    //如果前一个字符和对应的字符下标对应的字符相等,相应存储位就加1
    //如果不等,就与该下标对应的下标字符对比,直到相等,如果不相等就归为-1
        j=visit[i];
        while(i<str.length-1)
        {
            if(str.a[i]==str.a[j])
            {
            i++;
            visit[i]=++j;
            }
            else
            {
            while(str.a[i]!=str.a[j]&&j!=-1)
            j=visit[j];
            i++;
            visit[i]=++j;
            }
        }
    }

第二步,开始正式的字符串比对匹配

思想,与上文模式串思想类似,将待匹配的字符串与模式串一个一个位置进行匹配,如果两者相等,则模式串与字符串分别向前移一位匹配,如果不相等,则与模式串的下标进行匹配,直到相等为止,按此规则,直到所有的模式串匹配完,匹配成功返回成功结点的位置,反之返回0;

int pos(str str1,str str2)
{
    int i=0,j=0;
    //将相应位置的两个字符对比,如果相等,则比对下面两个字符,反
    //之,就对比字符下标的的字符,一直到相等或者字符标志为-1即
    //可,最后str2.length-1字符匹配成功即可
    while(j<str2.length&&i<str1.length)
    {
        if(a[i]==b[j])
        {
            i++;
            j++;
        }
        else
        {
            while(a[i]!=b[j]&&j!=-1)
            {
                j=next[j];
            }
            i++;
            j++;
        }
    }
    if(j==str2.length)
    {
        return i-1-str2.length;
    }
    else//如果没有找到相应匹配的串,就归为0
    {
        return 0;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_42373888/article/details/81461219
今日推荐