可用于KMP算法的求一个字符串的最长相同前后缀长度

最近学了求一个小字符串在大字符串中的位置算法,涉及到了一个KMP算法,这个算法颇费了我一番脑子,写出来了,还有待记忆。
在这里,我把求一个字符串的最长相同前后缀长度的算法简单说明一下。
要求最长相同前否前后缀,就需要把前面也联系起来。
先举个最简单的例子,设要求的字符串为a = “bbabaabb”。显而易见,人眼一看就是2了。但机器要怎么做呢?
我们设一个int next[8] = 0;
(以0为开头)第0个一定为0,即next[0] = 0;
比较下一个,比较a[1]和a[next[0]],相等就再加1,即next[1] = next[0] + 1 = 2;
比较下一个, 比较a[2]和a[next[1]],因为不相等,就和a[0]比较,不相等,所以next[2] = 0;
比较下一个,比较a[3]和a[next[2]],因为不相等,就和a[0]比较,相等,所以next[3] = 1;
比较下一个,比较a[4]和a[next[3]],因为不相等,就和a[0]比较,不相等,所以next[4] = 0;
比较下一个,比较a[5]和a[next[4]],因为不相等,就和a[0]比较,不相等,所以next[4] = 0;
比较下一个,比较a[6]和a[next[5]],相等就再加1,即next[6] = next[5] + 1 = 1;
比较下一个,比较a[7]和a[next[6]],相等就再加1,即next[7] = next[6] + 1 = 2;
因为已经到了最后了,所以所得值就是next[7]的值2;
总结一些规律:
(1)数组next中的值要么比前一个值多1,要么为1,要么为0;
(2)
如果a[i] == a[next[i - 1] + 1]
{
则next[i] = a[next[i - 1]] + 1;
}
如果不相等
{
如果a[i] == a[0]
{
则next[i] = 1;
}
如果不相等
{
则next[i] = 0;
}
}
算法肯定是要贴出来的,如下所示(这里面有fun1和fun2两个额外函数,fun1为我要讲述的算法):



#include

 

#define N 11

 

int next[11] = { 0 };

char a[N] = "abaabbabaab";

char s[2 * N] = "abaabaababaabbabaabbba";

 

void fun1()

{

    for (int i = 1; i < N; i++)

    {

         int j = next[i - 1];

         if (a[i] == a[j])

         {

             next[i] = j + 1;

         }

         else

         {

             if (a[i] == a[0])

             {

                  next[i] = 1;

             }

             else

             {

                  next[i] = 0;

             }

         }

    }

}

 

int fun2()

{

    int j = next[0];

    for (int i = 0; i < 2 * N; )

    {

         if (s[i] == a[j])

         {

             i++;

             j++;

         }

         else

         {

             j = next[j];

         }

         if (j == N)

         {

             return i - j;

         }

    }

 

    return -1;

}

 

void main()

{

    fun1();

    for (int i = 0; i < N; i++)

    {

         printf("%-4c", a[i]);

    }

    printf("\n");

    for (int i = 0; i < N; i++)

    {

         printf("%-4d", next[i]);

    }

    printf("\n");

    int m = fun2();

    if (m == -1)

    {

         printf("没有找到!");

    }

    else

    {

         printf("相应的位置为%d", m);

    }

    getchar();

}


加一张这个函数产生的效果
可用于KMP算法的求一个字符串的最长相同前后缀长度_第1张图片
注意,在KMP算法中的数都要减1。
上面写的比较粗心,如果有问题,还请指教。
另外我讲的可能还是不够形象,更详细的解释可以参考这篇文章:http://www.cnblogs.com/SYCstudio/p/7194315.html

你可能感兴趣的:(可用于KMP算法的求一个字符串的最长相同前后缀长度)