KMP算法代码&BF算法代码

转自:http://blog.csdn.net/likid1412/article/details/7908984

BF算法是一种简单模式匹配算法BF算法,时间复杂度为O(m*n)。

KMP算法是一种改进的字符串模式匹配算法,时间复杂度为O(m+n).。

下面只贴出了代码,详细的算法介绍可参考任一本算法书籍或者该网页:http://www.cppblog.com/oosky/archive/2006/07/06/9486.html(该网页我没看过,百度来的,建议还是看算法书好了)。

注:KMP的代码基本是自己写的,get_next()函数是改进过的。BF代码直接从书上摘录的。参考书籍:《数据结构(C语言版)》

[cpp]  view plain copy
  1. #include<iostream>  
  2.   
  3. using namespace std;  
  4.   
  5. void get_next(const char* t, int* next, int len);  
  6. int index_KMP(const char* s,const char* t, int pos = 0);  
  7. int index_BF(const char* s, const char* t, int pos = 0);  
  8.   
  9. int main()  
  10. {  
  11.     const char* S = "dasdadsdsd";  
  12.     const char* T = "dasdasd";  
  13.   
  14.     cout << "use BF:" << endl;  
  15.     int index = index_BF(S, T);  
  16.     if (index > -1)  
  17.         cout << T << " is a substring of " << S << " at index " << index + 1 << endl;  
  18.     else  
  19.         cout << T << " is not a substring of " << S << endl;  
  20.   
  21.     cout << "use KMP:" << endl;  
  22.     index = index_KMP(S, T);  
  23.     if (index > -1)  
  24.         cout << T << " is a substring of " << S << " at index " << index + 1 << endl;  
  25.     else  
  26.         cout << T << " is not a substring of " << S << endl;  
  27.   
  28.     return 0;  
  29. }  
  30.   
  31. // O(m+n)  
  32. int index_KMP(const char *S, const char *T, int pos)  
  33. {  
  34.     // 求T在主串S中第pos个字符之后的位置的KMP算法。  
  35.     // 其中,T非空,1 <= pos <= strlen(S)。  
  36.     int s_len = strlen(S);  
  37.     int t_len = strlen(T);  
  38.     if(t_len > s_len)  
  39.     {  
  40.         return -1;  
  41.     }  
  42.   
  43.     int *next = new int[t_len];  
  44.     get_next(T, next, t_len);   // 获取模式串T的next值  
  45.   
  46.     int count = 0;  
  47.     int i = pos, j = 0;  
  48.     while ((i < s_len) && (j < t_len))  
  49.     {  
  50.         if ((j == -1) || (S[i] == T[j]))  
  51.         {  
  52.             ++i;  
  53.             ++j;  
  54.         }  
  55.         else  
  56.             j = next[j];  
  57.         ++count;  
  58.     }  
  59.     delete[] next;  
  60.     next = NULL;  
  61.   
  62.     cout << "\nKMP loop count: " << count << endl;  
  63.   
  64.     if (j >= t_len)  
  65.         return i - j;  
  66.     else  
  67.         return -1;  
  68. }  
  69.   
  70. void get_next(const char* t, int* next,int len)  
  71. {  
  72.     // 求模式串T的next函数修正值并存入数组next。  
  73.     int j = 0;      //求解每个next[j]  
  74.     next[0] = -1;   //递推基本条件,然后求解next[j+1]  
  75.     int k = -1;     //向后递推位置下标  
  76.     /* 
  77.     next[j]=k    =>T0...Tk-1=Tj-k...Tj-1 
  78.     求解next[j+1] 
  79.     1> 如果T0..Tk-1Tk=Tj-k...Tj-1Tj=>next[j+1]=k+1=next[j]+1; 
  80.     2>Tk<>Tj,next[k]=k', 如果Tj=Tk'=>next[j+1]=k'+1=next[k]+1=next[next[j]]+1; 
  81.     3>依次递推 最后情况next[j+1]=next[0]+1=0,即 
  82.     */  
  83.     for (int condition = len - 1; j < condition;)  
  84.     {  
  85.         if ((k == -1) || (t[j] == t[k]))  //k==-1证明已经与t[0]不匹配了,此时next[j+1]=0;  
  86.         {  
  87.             ++j;  
  88.             ++k;  
  89.             if (t[j] != t[k])     
  90.                 next[j] = k;  
  91.             else  
  92.                 next[j] = next[k];    
  93.             // 若Tj = Tk,则当主串中字符Si和Tj比较不等时,不需要再和Tk进行比较,  
  94.             // 而直接和TNext[k]进行比较,即此时的next[j]应和next[k]相同。  
  95.             //cout << "next[" << j << "]: " << next[j] << endl;  
  96.         }  
  97.         else  
  98.             k = next[k];  
  99.     }  
  100. }  
  101.   
  102. // O(m*n)  
  103. int index_BF(const char* S, const char* T, int pos)  
  104. {  
  105.     // 返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数值为0  
  106.     // 其中,T非空,0 <= pos < strlen(S)  
  107.     int s_len = strlen(S), t_len = strlen(T);  
  108.     int i = pos, j = 0;  
  109.     int count = 0;  
  110.     while (i < s_len && j < t_len)  
  111.     {  
  112.         if (S[i] == T[j])  
  113.         {  
  114.             ++i;  
  115.             ++j;  
  116.         }  
  117.         else  
  118.         {  
  119.             i = i - j + 1;  
  120.             j = 0;  
  121.         }  
  122.         ++count;  
  123.     }  
  124.     cout << "\nBF loop count: " << count << endl;  
  125.   
  126.     if (j == t_len)  
  127.         return i - j;  
  128.     else  
  129.         return -1;  
  130. }  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值