zoukankan      html  css  js  c++  java
  • KMP算法学习记录----《大话数据结构》部分匹配表学习部分

    如需转载,请保留本文链接.

    首先先将《大话数据结构》关于KMP算法的讲解部分贴上,本文不提供下载链接,也不会将电子书作为资料留百度云,需要电子书的各位,请自行寻找电子版.

    关于上述的KMP算法种的next数组的推导部分,一直不是很明白,本贴是关于上述部分的学习推导记录.

    以书中字符串为例:

    1|2|3|4|5|6|7|8|9|

    a|b|a|b|a|a|a|b|a|

    0|1|1|2|3|4|2|2|3|

    string T = "ababaaaba";

    int i = 1;j = 0;//这里最让我费解的其实是序列号,只要明白本书中的KMP算法,序列号都是从1开始计算的,就会好理解了很多.

    next[1] = 0;

    while(i<T[0])//或者写成T.Length

    {

      if(j == 0 || T[i] == T[j])//T[i]代表后缀的第一个字符,T[j]代表前缀中的某一个字母,j记录了当前相等的字符个数

      {

        ++i;

        ++j;

        next[i] = j;

      }

      else

      {

        j = next[j];//所有部分匹配值均取自j的数据,且,满足if条件时,计算出的是下一个i值对应的部分匹配数据,这就意味着next[j]的值永远小于j,

            //但是关于j的回溯个数,目前并没有很好的理解,初步认为只是利用next[j]值小于j值进行回溯,跟当前的前后缀相等字符数无关

      }

    }

    以下为while循环详细分解,记录学习过程.

    第一步:由于前缀与后缀均来自于子串,部分匹配表则是子串的自我匹配程度反应,那么当子串长度为1时,不存在前缀与后缀,由此可得:next[1] = 0;

    第二步:i = 1;j = 0;满足if判断条件,i,j++;next[2] = 1;此时i = 2;j = 1;

    第三步:i = 2;j = 1;

      T[i = 2] = "b";

      T[j = 1] = "a";-------------"ab"[前缀与后缀相等个数的下一字符索引值,后缀字符]

      else

      {

        j = next[j] = next[1] = 0;

      }

      j = 0;

      i,j++;

      next[3] = 1;//此时i = 3;j = 1;

    第四步:i = 3;j = 1;

      T[i = 3] = "a";

      T[j =1] = "a";----------"aba"[前缀与后缀相等的个数的下一字符索引值,b,后缀字母]

      i,j++;

      next[4] = 2;//此时i = 4;j = 2;

    第五步:i = 4;j = 2;

      T[i = 4] = "b";

      T[j = 2] = "b";----------"abab"[a,前缀与后缀相等的个数的下一字符索引值,a,后缀字母]

      i,j++;

      next[5] = 3;//此时i = 5;j = 3;

    第六步:i  = 5;j = 3;

      T[i = 5] = "a";

      T[j = 3] = "a";-----------"ababa"[a,b,前缀与后缀相等的个数的下一字符索引值,b,后缀字母]

      i,j++;

      next[6] = 4;//此时i = 6;j = 4;

    第七步:i = 6;j = 4;

      T[i = 6] = "a";

      T[j = 4] = "b";-------"ababaa"[a,b,a,前缀与后缀相等的个数的下一字符索引值,a,后缀字母]

      else

      {

        j = next[4] = 2;//j值进行回溯

      }

      j = 2;

      T[j = 2] = "b";-------------"ababaa"[a,?,a,b,a,后缀字母]不确定含义,暂用问号代替

      elst

      {

        j = next[2] = 1;//j值进行回溯

      }

      j = 1;

      T[j = 1] = "a";---------------"ababaa"[?,b,a,b,a,后缀字母]

      与T[i = 6]进行对比

      i,j++;

      next[7] = 2;//此时i = 7;j = 2;

    第八步:i = 7;j = 2;

      T[i = 7] = "a";

      T[j = 2] = "b";---------"ababaaa"[a,前缀与后缀相等的个数的下一字符索引值,a,b,a,a,后缀字母]

      else

      {

        j = next[j] = next[2] = 1;

      }

      j = 1;

      T[j = 1] = "a";-----------------"ababaaa"[前缀与后缀相等的个数的下一字符索引值,b,a,b,a,a,后缀字母]

      i,j++;

      next[8] = 2;//此时i= 8;j = 2;

    第九步:i = 8;j = 2;

      T[i = 8] = "b";

      T[j = 2] = "b";---------------"ababaaab"[a,前缀与后缀相等的个数的下一字符索引值,a,b,a,a,a,后缀字母]

      i,j++;

      next[9] = 3;//此时i = 9;j = 3;

    此时关于字符串"ababaaaba"的部分匹配表完全推导完毕,答案与书上结果一直,但是关于i = 6时,j回溯如何做解释,还需要再看,我在另外的字符串"aaaaabbbc"中,j的回溯每次回溯一位,得到的部分匹配表为:012345511,欢迎留言指正,结束.

  • 相关阅读:
    linux 内存映射-ioremap和mmap函数
    vue 模板语法-插值的操作(12-22)
    chrome浏览器json插件
    vue初识(1-11)2020-10-27
    后盾人:JS课程第一章(11-18)2020-10-25
    博客园美化
    chrome 设置自动刷新网页
    二叉树的层次遍历
    poj 2905 双向队列(待补充)
    poj 2159 D
  • 原文地址:https://www.cnblogs.com/yikecaidechengzhangshi/p/8576061.html
Copyright © 2011-2022 走看看