BF算法与KMP算法

墨蓝 2023-02-28 12:48 193阅读 0赞

BF算法与KMP算法都是用来查找主串中子串的位置,也就是模式匹配。
BF算法的简单粗暴,缺点是每趟匹配不成功时,存在大量回溯,导致程序效率低下,而KMP算法充分利用了成功匹配部分的结果,保证了主串游标不回溯,通过模式串向右滑动代替模式串游标回溯,大大提高了程序运行效率。
简单的了解了一下BF和KMP算法的作用和优缺点后,我们先来看一下具体的代码和细节

先看BF算法(这个算法比较简单,就不多说了直接上代码)

  1. #include<iostream>
  2. #include<string.h>
  3. using namespace std;
  4. int BF(char S[],char T[])
  5. {
  6. int i=0, j=0,len1=strlen(S),len2=strlen(T);
  7. for(i;i<len1;i++)
  8. {
  9. if(S[i]==T[j])
  10. j++;
  11. else
  12. {
  13. i=i-j+1;
  14. j=0;
  15. }
  16. if(j==len2)return i-j+1;
  17. }
  18. return -1;
  19. }
  20. int main()
  21. {
  22. char a[20],b[5];
  23. cin>>a>>b;
  24. cout<<BF(a,b);
  25. }

关于KMP算法,主要的难点在于next数组的计算
在这之前,我们已经知道了主串指针i可以不回溯,模式串向右滑动到新的比较起点k,并且k仅与模式串T有关,
那么如何由当前部分匹配结果确定模式向右滑动的新比较起点k?
模式应该向右滑动多远才是效率最高的?

解决了这两个问题,next的计算也就简单了watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ2NjAxMzM4_size_16_color_FFFFFF_t_70
这样,我们通过T[0]-T[K-1]=T[J-K]~T[J-1]可以确定每次匹配失败时应该回溯的位置k,而滑动多远才是效率最高的问题取k中最大值即可watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQ2NjAxMzM4_size_16_color_FFFFFF_t_70 1
接下来是具体的代码

  1. #include<string>
  2. #include<iostream>
  3. using namespace std;
  4. void Getnext(string t, int next[])
  5. {
  6. int j = 0, k = -1;
  7. next[0] = -1;
  8. while (j < t.length() )
  9. {
  10. if (k == -1 || t[j] == t[k])
  11. {
  12. j++; k++;
  13. next[j] = k;
  14. }
  15. else k = next[k];
  16. }
  17. }
  18. int KMP(string p, string t)
  19. {
  20. int i = 0, j = 0;
  21. int* next = new int[t.length()];
  22. Getnext(t, next);
  23. for (int i = 0; i < t.length(); i++)
  24. cout << next[i] << " ";
  25. cout << endl;
  26. while (i < p.length() && j < t.length())
  27. {
  28. if (p[i] != t[j])
  29. {
  30. j = next[j];//匹配失败,模式串向右滑动至next[j](也就是之前说的k)
  31. }
  32. if (p[i] == t[j] || j == -1)
  33. {
  34. j++; i++;
  35. }
  36. }
  37. if (j >= t.length())return i - t.length();
  38. else return -1;
  39. }
  40. int main()
  41. {
  42. string p = "DABCDDACBAEDABCFDABCDABD";
  43. string t = "DABCDABD";
  44. cout << " ";
  45. for (int i = 0; i < t.length(); i++)
  46. cout << t[i] << " ";
  47. cout << endl;
  48. cout<<KMP(p, t);
  49. }

发表评论

表情:
评论列表 (有 0 条评论,193人围观)

还没有评论,来说两句吧...

相关阅读

    相关 字符串BF算法KMP算法

    什么是串 数据结构中,字符串要单独用一种存储结构来存储,称为串存储结构。这里的串指的就是字符串。字符串通常是由零个或多个字符组成的有限序列。 一般地,由n个字符串构成的

    相关 Java-串(BFKMP算法)

    BF 一种简单的模式匹配算法,目的是寻找模式串p是否在目标串s中有出现。 思想:先从第一个字符开始匹配,如果p\[j\]==s\[i\],那么继续向下比较,一旦不相等,

    相关 BF算法KMP算法

    BF算法与KMP算法都是用来查找主串中子串的位置,也就是模式匹配。 BF算法的简单粗暴,缺点是每趟匹配不成功时,存在大量回溯,导致程序效率低下,而KMP算法充分利用了成功匹

    相关 BF算法KMP算法详解

    串匹配问题 给定两个字符串S和T,在主串S中查找子串T的过程称之为串匹配(模式匹配),T称之为模式。这样一类的问题在实践中应用非常广泛。在文本处理系统、操作系统、编译系统、数