字符串匹配的KMP算法实现

问题源自数据结构书。

 

 问题:字符串src中含有模式串pat的个数

举例:src= 00000111111111101010111010101001

pat=110

src中含有多少个pat?

 

分析:

没有回溯的KMP算法。

1)首先实现一个next[]数字,其中的值,是匹配失误之后的下一次匹配的位置。next[0]=-1; next[1]=0;后面的多数都不是0。这个实际是一个KMP的匹配过程;

2)然后把pat在src中进行匹配,又是一个KMP的匹配过程。

 

代码:

  1. const int pat_length = 3;
  2. int src_length = 0;
  3. // 计算next[],一次KMP算法
  4. bool nextPos(const char* pPat, int* next)
  5. {
  6.     int k = -1;
  7.     next[0] = k;
  8.     
  9.     int index = 0;
  10.     do {
  11.         if ( (-1 == k) || pPat[index] == pPat[k] )
  12.         {
  13.             k++;
  14.             index++;
  15.             next[index] = k;
  16.         }
  17.         else
  18.         {
  19.             k = next[k];
  20.         }
  21.     }  while ( index < pat_length - 1 );
  22.     return true;
  23. }
  24. // pat与src进行匹配,一次KMP算法
  25. int match(const char* pSrc, const char* pPat, const int* next)
  26. {
  27.     int times = 0;
  28.     
  29.     int srcIndex = 0;
  30.     int patIndex = 0;
  31.     
  32.     while ( patIndex < pat_length && srcIndex < src_length )
  33.     {
  34.         if ( patIndex == -1 || pSrc[srcIndex] == pPat[patIndex] )
  35.         {
  36.             patIndex++;
  37.             srcIndex++;
  38.         }
  39.         else
  40.         {
  41.             patIndex = next[patIndex];
  42.         }
  43.         
  44.         if ( patIndex == pat_length )   //match
  45.         {
  46.             times++;
  47.             patIndex = 0;
  48.         }
  49.     }    
  50.     return times;
  51. }
  52. //测试程序
  53. int main(int argc, char* argv[])
  54. {
  55.     using namespace std;    
  56.     char src[] = "acabaabaabcacaabc";
  57.     char pat[] = "abaabcac";
  58.     src_length = sizeof(src);
  59.     int  next[pat_length];
  60.     int times = 0;
  61.     if ( nextPos(pat, next) )
  62.     {
  63.         times = match(src, pat, next);
  64.         cout << "times:" << times << endl;
  65.     }
  66.     
  67.     getchar();
  68.     return 0;
  69. }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值