KMP字符串匹配算法的解析及记忆

KMP字符串匹配算法的解析及记忆


void kmp_pre(char x[],int m,int fail[])
{//x是字符子串数组,也就是模式串,m是总长度
    int i,j;
    j = fail[0] = -1;//这个一定要初始化的
    i = 0;
//首先要明确一点,无论x[i]等不等于x[j],i是在不断前进的,也就是说子串每一个字符都有对应的fail序号
(也就是查找失败后返回与子串前缀相同的最大长度)举个例子:
假如子串abaabcac,
母串为  abaabaabcac...
那么查找到第6个位置发现不匹配,令j=fail[6]=2(子串第六个位置前面与前缀最大的公共相同序列为ab,所以最大长度为2=fail[6]),
所以下一次匹配就从j=2+1=3 子串的第三个位置开始对比,即母串的第6个位置直接与子串的第3个位置对比,也就是
aba(ab)aabcac...
   (ab)aabcac这样子进行对比。
所以以下过程就是求子串各个字符对应的与前缀的最大公共序列字符数
    while (i < m)
    {
        while (j != -1 && x[i] != x[j]) j = fail[j];
        fail[++i] = ++j;
    }//
//举个例子:abcabc求fail数组
//f[1]=0,x[1]!=x[0],j=f[0]=-1;f[2]=0;x[2]!=x[0];j=f[0]=-1;f[3]=f[0];
//x[3]=x[0],f[4]=1;x[4]=x[1],f[5]=2;x[5]=x[2],f[6]=3;
}

int kmp_count(char x[],int m,char y[],int n)//这个查找还比较好理解
{
    int i = 0,j = 0;
    int ans = 0;
    while (i < n)
    {
        while (j != -1 && y[i] != x[j]) j = fail[j];//与上面是不是很类似?直接看上面例子吧,比较好理解
      i++;j++; //得到最大公共序列字符数之后还要+1,因为要从不相同的一个字符开始对比              
        if (j >= m)
        {
            ans++;
            j = fail[j];
        }
    }
    return ans;
}


你可能感兴趣的:(ACM算法,C++,字符串KMP)