飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 3834|回复: 7

[C/C++] 一个类KMP的算法

[复制链接]

该用户从未签到

发表于 2014-9-29 18:31:54 | 显示全部楼层 |阅读模式
看了一篇KMP算法的文章,对数学公式有点没绕明白,干脆自己琢磨琢磨吧。
Link: http://blog.csdn.net/yaochunnian/article/details/7059486

自己在纸上画了画,逻辑应该是找重复,简单实现了一个自己的逻辑,改天在继续研究。
我的想法是这样的
Test1 :
a a a b
0 0 1 2
Test2 :
a b a b c d
0 0 0 1 2 0
然后根据返回值 j,来判断如何处理。


  1. void GetNextval(char const* pstr, int nlen, int* Value)   
  2. {   
  3.     int i = 1;
  4.     int k = 0;
  5.     int nMax = 0;
  6.     memset( Value, 0, nlen * sizeof(int));
  7.     while( i < nlen )   
  8.     {   
  9.         // "abaabac";
  10.         if( *(pstr + i) == *(pstr) )   //循环的if部分   
  11.         {
  12.             nMax = k = 0;
  13.             do
  14.             {
  15.                 nMax ++;
  16.                 Value[i + k + 1] = nMax;
  17.                 k++;
  18.             } while ( k < (nlen - i) &&
  19.                 *(pstr + i + k) == *(pstr + k) );

  20.             i += k;
  21.             continue;
  22.         }
  23.         i++;
  24.     }
  25. }

  26. void GetNextvalEx(char const* pstr, int nlen, int* Value)   
  27. {   
  28.     int i = 1;
  29.     int k = 0;
  30.     int nMax = 0;
  31.     memset( Value, 0, nlen * sizeof(int));
  32.     while( i < nlen-1 )   
  33.     {   
  34.         // "aaaaaab";
  35.         // "0012345";
  36.         if( * pstr  == *(pstr + i) )   //循环的if部分   
  37.         {
  38.             nMax = k = 0;
  39.             do
  40.             {
  41.                 ++k ;
  42.                 Value[i + k ] = ++nMax;
  43.             } while ( i + k  < nlen-1  &&
  44.                 *(pstr + k) == *(pstr + i + k) );

  45.             i += k;
  46.             continue;
  47.         }
  48.         i++;
  49.     }
  50. }

  51. int KmpSearch(char const* src, int len1, char const* dest, int len2, int const* Value, int pos)   
  52. {   
  53.     int i = pos;   
  54.     int j = 0;
  55.     int nIndex = 0;
  56.     while ( i < len1 && j < len2 )   
  57.     {   
  58.         if( src[i] == dest[j] )   
  59.         {   
  60.             ++i;   
  61.             ++j;   
  62.         }   
  63.         else   
  64.         {   
  65.             j = Value[j];
  66.             if ( src[i] != dest[j] )
  67.             {
  68.                 if ( j != 0 ) // j > 0
  69.                     j = 0;
  70.                 ++i;
  71.             }
  72.         }   
  73.     }   
  74.     if( j == len2 )   
  75.         nIndex = i-len2;   
  76.     else   
  77.         nIndex = -1;   

  78.     return nIndex;
  79. }

  80. int   main()  
  81. {  
  82.     std::string src = "abababc";  
  83.     std::string prn = "abc";  
  84.     int* nextval = new int[prn.size()];  
  85.     GetNextval(prn.data(), prn.size(), nextval);
  86.     int nIndex = KmpSearch(src.data(), src.size(), prn.data(), prn.size(), nextval, 0);
  87.   // delete ...
  88. }

复制代码


PYG19周年生日快乐!

该用户从未签到

 楼主| 发表于 2014-9-29 18:37:53 | 显示全部楼层
直接写的代码 转过来大家看下这样是否更好理解KMP的实现 没有做过测试 若有BUG还望反馈 ~
PYG19周年生日快乐!
  • TA的每日心情
    开心
    2018-9-27 19:17
  • 签到天数: 31 天

    [LV.5]常住居民I

    发表于 2014-9-29 21:08:32 | 显示全部楼层
    果断顶!
    那篇博文的原作者后来重新写了一篇,比较好理解了,关键是所谓的“前缀、后缀”,前后缀中间的部分为何不用证明不太明白,没学过数论。
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2018-9-27 19:17
  • 签到天数: 31 天

    [LV.5]常住居民I

    发表于 2014-9-29 21:45:55 | 显示全部楼层
    经测试,一切正常!
    PYG19周年生日快乐!
  • TA的每日心情
    慵懒
    2015-8-14 00:08
  • 签到天数: 25 天

    [LV.4]偶尔看看III

    发表于 2014-9-29 22:28:06 | 显示全部楼层
    我也来占坐学习。。。
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2015-9-18 09:23
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2015-1-26 16:35:45 | 显示全部楼层
    感谢楼主分享!
    PYG19周年生日快乐!
  • TA的每日心情
    擦汗
    2019-3-1 23:51
  • 签到天数: 559 天

    [LV.9]以坛为家II

    发表于 2015-6-2 18:30:24 | 显示全部楼层
    居然在这里看到了nisy的kmp源码,测试一下。
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表