算法——字符串匹配之朴素算法

前言

    本文介绍的是字符串匹配最简单的算法--朴素字符串匹配算法。该算法的原理非常简单,就是通过一个循环找到所有有效偏移,即对检查是否满足条件。算法没有进行预处理,只是对其进行匹配处理,算法过程中是每次移动一位的比较字符,所以时间复杂度是非常大O((n-m+1)m)。

通俗来说就是在长字符串中寻找已知的段字符串!

算法实现

    根据该算法的描述,这里给出算法导论中的伪代码,并根据伪代码给出具体实现代码,从代码中很清晰地看到该算法的时间复杂度。注:字符下标是从0开始的。

伪代码:

 

 
  1. NAIVE_STPRING_MATCHER(T,P)

  2. n = T.length;

  3. m = P.length;

  4. for(s=0;s <= n-m;s++)

  5. if P[1..m]==T[s+1..s+m];

  6. print "Pattern occurs with shift" s;


C++源码实现:

 

 

 
  1. #include <iostream>

  2. #include <string>

  3.  
  4. using namespace std;

  5.  
  6. int NAIVE_STPRING_MATCHER(const string &T,const string &P);

  7.  
  8.  
  9. int main()

  10. {

  11. string T = "abcdefghijk";

  12. string P = "defg";

  13.  
  14. int s = NAIVE_STPRING_MATCHER(T,P);

  15. if(s>=0)

  16. cout<<"Pattern occurs with shift:"<<s<<endl;

  17. else

  18. cout<<"Not macth the P in the T. "<<endl;

  19.  
  20. system("pause");

  21. return 0;

  22. }

  23.  
  24. int NAIVE_STPRING_MATCHER(const string &T,const string &P)

  25. {

  26. int n = T.length();

  27. int m = P.length();

  28.  
  29. if(n < m) return -1;

  30. int s_length = n-m;

  31.  
  32. for (int s = 0; s <= s_length; s++)

  33. {

  34. bool flag = false;

  35. for(int i = 0;i < m;i++)

  36. {

  37. if(T[s+i]==P[i])

  38. flag = true;

  39. else

  40. {

  41. flag = false;

  42. break;

  43. }

  44. }

  45.  
  46. if(flag)

  47. return s;

  48. }

  49. return -1;

  50. }

    注意:以上的C++源码只可以找出字符串中一次匹配,例如T=abcdefghijkdefg,P=defg,则只能找出第一个有效偏移s=3,第二个有效偏移s=11不能找出。

    为了能够找出所有匹配项,我们可以在第一次匹配成功后,继续移动整个模式串,把所有匹配成功的位置找出来。只需要对上面的源码进行修改即可,源码如下:

 

 
  1. #include <iostream>

  2. #include <string>

  3.  
  4. using namespace std;

  5.  
  6. void NAIVE_STPRING_MATCHER(const string &T,const string &P);

  7.  
  8.  
  9. int main()

  10. {

  11. string T = "abcdefghijkdefg";

  12. string P = "defg";

  13.  
  14. NAIVE_STPRING_MATCHER(T,P);

  15. system("pause");

  16. return 0;

  17. }

  18.  
  19. void NAIVE_STPRING_MATCHER(const string &T,const string &P)

  20. {

  21. int n = T.length();

  22. int m = P.length();

  23.  
  24. if(n < m) cout<<"the length of P larger than T";

  25. int s_length = n-m;

  26.  
  27. for (int s = 0; s <= s_length; s++)

  28. {

  29. bool flag = false;

  30. for(int i = 0;i < m;i++)

  31. {

  32. if(T[s+i]==P[i])

  33. flag = true;

  34. else

  35. {

  36. flag = false;

  37. break;

  38. }

  39. }

  40.  
  41. if(flag)

  42. cout<<"match successed, the s is:"<<s<<endl;

  43. }

  44. }

或者:

 

 
  1. #include <iostream>

  2. #include <string>

  3.  
  4. using namespace std;

  5.  
  6. void NAIVE_STPRING_MATCHER(const string &T,const string &P);

  7.  
  8.  
  9. int main()

  10. {

  11. string T = "abcdefghijkdefg";

  12. string P = "defg";

  13.  
  14. NAIVE_STPRING_MATCHER(T,P);

  15. system("pause");

  16. return 0;

  17. }

  18.  
  19. void NAIVE_STPRING_MATCHER(const string &T,const string &P)

  20. {

  21. int M = P.length();

  22. int N = T.length();

  23.  
  24. for (int s = 0; s <= N - M; s++)

  25. {

  26. int j;

  27. for (j = 0; j < M; j++)

  28. if (T[s+j] != P[j])

  29. break;

  30. if (j == M)

  31. cout<<"Pattern found at index:"<<s<<endl;

  32. }

  33. }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值