637-字符串模式匹配-BF算法

水深无声 2022-09-12 07:55 202阅读 0赞

字符串模式匹配
模式串(或子串)在主串中的定位操作通常称为串的模式匹配,它是各种串处
理系统中最重要的运算之一。

BF算法

布鲁特-福斯算法
从主串的第一个字符起与模式串的第一个字符比较,若相等,则继续逐个字
符进行后续比较,否则从主串的第二个字符起与模式串的第一个字符重新开始比较,直至模式串中每个字符依次与主串中的一个连续的字符序列相等时为止,此时称为匹配成功;如果在主串中不存在与模式串相同的子串,则匹配失败。

图解过程

给定主串“ABCDABCDABBABCDABCDABDD”,子串“ABCDABD”
1、第一趟比较,先比较 A,然后是 BCDAB。
在这里插入图片描述
在比较最后一个字符 D 时,不匹配。
在这里插入图片描述
2、第二趟比较,主串回退到比前一趟加 1 的位置。子串从 0 开始。第一个就不匹配。结束本趟。
在这里插入图片描述
3、第三趟比较,主串回退到比前一趟加 1 的位置,子串从 0 开始。第一个还是不匹配。同样结束本趟。
在这里插入图片描述
……
i、第 i 趟比较,找到可以匹配的子串
在这里插入图片描述

  1. /****************************************************************
  2. * 函数名称:searchFS
  3. * 功能描述:布鲁特-福斯模式匹配
  4. * 参数说明:src, 主串
  5. * sub, 模式串
  6. * 返 回 值:-1,表示不成功,非0的值表示模式串sub在主串src的位置
  7. *****************************************************************/
  8. int searchFS(const char *src, const char*sub)
  9. {
  10. int i, j;
  11. i = 0;
  12. j = 0;
  13. int strLen = strlen1(src);
  14. int tLen = strlen1(sub);
  15. while (i<strLen && j<tLen)
  16. {
  17. if (src[i] == sub[j])
  18. {
  19. ++i;
  20. ++j;
  21. }
  22. else
  23. {
  24. //主串回退
  25. i = i - j + 1;
  26. //子串
  27. j = 0;
  28. }
  29. }
  30. if (j >= tLen)
  31. {
  32. return (i - tLen);
  33. }
  34. return -1;
  35. }
  36. int searchFS(const char *src, const char*sub, int pos)
  37. {
  38. int i, j;
  39. i = pos;
  40. j = 0;
  41. int strLen = strlen1(src);
  42. int tLen = strlen1(sub);
  43. while (i<strLen && j<tLen)
  44. {
  45. if (src[i] == sub[j])
  46. {
  47. ++i;
  48. ++j;
  49. }
  50. else
  51. {
  52. //主串回退
  53. i = i - j + 1;
  54. //子串
  55. j = 0;
  56. }
  57. }
  58. if (j >= tLen)
  59. {
  60. return (i - tLen);
  61. }
  62. return -1;
  63. }
  64. /****************************************************************
  65. * 函数名称:searchFSAll
  66. * 功能描述:查找模式串在主串中所有的出现的位置
  67. * 参数说明:locArr, 位置的数组
  68. * src, 主串
  69. * sub, 模式串
  70. * 返 回 值:0,表示没有匹配的,非值,表示有匹配的个数
  71. *****************************************************************/
  72. int searchFSAll(int locArr[],const char *src, const char *sub)
  73. {
  74. //调用
  75. int i = 0;
  76. int srcLen = strlen1(src);
  77. int subLen = strlen1(sub);
  78. //int res = searchFS(src, sub, 0);
  79. //if (res != -1)
  80. //{//找到了 , res是当前的一个位置 (排除 ABABACDABAC ABA)
  81. // //记录res
  82. // locArr[i] = res;
  83. // i++;
  84. // res += subLen;
  85. // res = searchFS(src, sub, res);
  86. //}
  87. int res = 0;
  88. int bj = 0;
  89. while ((res = searchFS(src, sub, res)) != -1)
  90. {
  91. ++bj;//表示找到一个,加1
  92. locArr[i] = res;
  93. i++;
  94. res += subLen;
  95. }
  96. return bj;
  97. }

代码实现

  1. #include<stdio.h>
  2. #include<string.h>
  3. int BF(const char*s,const char*p)
  4. {
  5. int lens=strlen(s);
  6. int lenp=strlen(p);
  7. if(s==NULL||p==NULL||lenp>lens) return -1;
  8. int i=0;
  9. int j=0;
  10. while(i<lens&&j<lenp)
  11. {
  12. if(s[i]==p[j])
  13. {
  14. i++;
  15. j++;
  16. }
  17. else
  18. {
  19. i=i-j+1;
  20. j=0;
  21. }
  22. }
  23. if(j==lenp)
  24. {
  25. return i-j;
  26. }
  27. return -1;
  28. }
  29. int main()
  30. {
  31. const char *s="ababcabcdabcde";
  32. const char *p="abcd";
  33. printf("%d\n",BF(s,p));
  34. return 0;
  35. }

在这里插入图片描述

增加pos位置的方法

  1. #include<stdio.h>
  2. #include<string.h>
  3. int BF(const char*s,const char*p,int pos)
  4. {
  5. int lens=strlen(s);
  6. int lenp=strlen(p);
  7. if(s==NULL||p==NULL||lenp>lens) return -1;
  8. int i=pos;
  9. int j=0;
  10. while(i<lens&&j<lenp)
  11. {
  12. if(s[i]==p[j])
  13. {
  14. i++;
  15. j++;
  16. }
  17. else
  18. {
  19. i=i-j+1;
  20. j=0;
  21. }
  22. }
  23. if(j==lenp)
  24. {
  25. return i-j;
  26. }
  27. return -1;
  28. }
  29. int main()
  30. {
  31. const char *s="ababcabcdabcde";
  32. const char *p="abcd";
  33. printf("%d\n",BF(s,p,6));
  34. return 0;
  35. }

性能分析

在这里插入图片描述

发表评论

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

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

相关阅读

    相关 串的模式匹配-BF算法

    串的模式匹配经常需要用到,判断一个字符串是否是另外一个字符串的一部分。前者称为子串或模式,后者成为主串或正文串。 先用最简单的BF算法实现串的模式匹配。 算法思路:先从主串