• KMP的使用——我的总结


      1 /*
      2     descr:    求KMP的next数组
      3     param:    p        模式串指针
      4     param:    nLeng    模式串有效字符长度
      5     param:    next    存放next值的数组,长度为nLeng+1
      6 */
      7 void initNextArray(char* p, int nLeng, int* next) 
      8 {    
      9     next[0] = nLeng;
     10     
     11     do {
     12 
     13         if (1== nLeng)
     14         {
     15             next[1] = 0;
     16             break;
     17         }
     18 
     19         if (2 == nLeng)
     20         {
     21             next[1] = 0;
     22             next[2] = 1;
     23             break;
     24                     
     25         }
     26 
     27         int k = 0;
     28 
     29         next[1] = 0;
     30         next[2] = 1;
     31 
     32         k = next[3 - 1];
     33 
     34         for (int i = 3; i <= nLeng; )
     35         {
     36 
     37             if ( p[i-1] ==p[k])
     38             {
     39                 ++k;                //说明前k个字符与当前i前面的k个字符完全匹配    
     40                 next[i] = k;        //说明当前i前面有k个字符是与最前面的k个字符是相同的
     41                 ++i;                //继续往后比较
     42             }
     43             else if (1 == k)
     44             {
     45                 k = 1;                //已经比较到第一个字符了,故k=1
     46                 next[i] = k;
     47                 ++i;
     48             }
     49             else
     50             {
     51                 k = next[k];
     52                 //此时i不需要动,继续往前找出现k个相同字符的位置
     53             }
     54 
     55         }
     56 
     57 
     58     } while (0);
     59 
     60     for (int i = 1; i <= nLeng; i++)
     61     {
     62         std::cout << next[i] << " ";
     63     }
     64 
     65     std::cout << endl;
     66     
     67 }
     68 
     69 int KMP_Search(char* pMain, char* pSub)
     70 {
     71 
     72 
     73     int nIndex = 0;
     74 
     75     int nMainLen = strlen(pMain);
     76 
     77     int nLen = strlen(pSub);
     78 
     79 
     80     char* pMain_bk = new char[nMainLen + 2];
     81     memset(pMain_bk, 0, nMainLen + 2);
     82 
     83     pMain_bk[0] = ' ';
     84     memcpy(&pMain_bk[1], pMain, nMainLen);
     85 
     86 
     87     char* pSub_bk = new char[nLen + 2];
     88     memset(pSub_bk, 0, nLen + 2);
     89 
     90     pSub_bk[0] = ' ';
     91     memcpy(&pSub_bk[1], pSub, nLen);
     92             
     93     int * next = new int[nLen+1];
     94     memset(next, 0, nLen+1);
     95 
     96     initNextArray(pSub_bk, nLen, next);
     97 
     98     int i = 1, k = 1;  //从下标1开始匹配
     99     //下标从1开始
    100     for (; i <= nMainLen && k<= nLen; )
    101     {
    102 
    103         if (0 == k)
    104         {
    105             //当前字符不匹配,且k=0,说明已经比较到第一个字符了,
    106             //则需要重新从第一个字符跟当前主串的后一个字符进行比较
    107             k = 1;
    108             ++i;
    109         }
    110         else if (pMain_bk[i] == pSub_bk[k])
    111         {
    112             ++k;
    113             ++i;        //当前字符匹配,则继续
    114         }
    115         else
    116         {
    117             k = next[k];    //退回合适的位置,i不变
    118         }
    119     }
    120 
    121     if (k > nLen)
    122     {
    123         nIndex = i - nLen;
    124     }
    125 
    126     return nIndex;
    127 
    128 }
    129 
    130 void    test_KMP()
    131 {
    132     char szMain[] = "12345Hello789";
    133     char szSub[] = "Hello";
    134 
    135     int nIndex = KMP_Search(szMain, szSub);
    136 
    137     std::cout << "1, nIndex=" << nIndex << endl;
    138 
    139     char szMain2[] = "12345Hello789";
    140     char szSub2[] = "456";
    141 
    142     nIndex = KMP_Search(szMain2, szSub2);
    143 
    144     std::cout << "2, nIndex=" << nIndex << endl;
    145 
    146     char szMain3[] = "ababaabca";
    147     char szSub3[] = "abc";
    148 
    149     nIndex = KMP_Search(szMain3, szSub3);
    150 
    151     std::cout << "3, nIndex=" << nIndex << endl;
    152 
    153 
    154 }
    155 
    156 int main(void)
    157 {
    158     test_getNext();
    159 
    160     getchar();
    161 }
  • 相关阅读:
    BeagleBone Black安装小米随身WiFi驱动方法
    java-ee,ssh整合博文收藏
    BeagleBoneBlack Linux开发相关链接收藏
    Debian7.7 wheezy 中源码安装emacs24
    GLOG使用注意事项
    centos、linux改变ll命令显示颜色
    centos中samba配置后始终连不上的绝招
    中兴电信光纤猫F612管理员密码获取方法
    STM32W108芯片的SWD在IAR7.30版本中不能用
    TRF7960天线参数试验
  • 原文地址:https://www.cnblogs.com/guoliushui/p/8981464.html
Copyright © 2020-2023  润新知