零、前言

为了下面便于说明,先定义两个名词,分别是主串和模式串。在字符串 A 中查找字符串 B,则 A 为主串,B 为模式串。

假设,主串中字符数量为 L1,模式串的字符数量为 L2 。

一、BF 算法

1、基本信息

BF 算法中的 BF 是 Brute Force 的缩写,中文叫作暴力匹配算法,也叫朴素匹配算法。

2、查找流程

从主串第一个位置开始匹配模式串,匹配完成之后,模式串移动一个字符,移动次数为 L1 - L2 + 1 次完成对主串的匹配。

上述过程中可以的优化的点是每次匹配时发现一个字符不一样时就可以中断当前匹配过程直接进入下一个匹配。

3、时间复杂度

单次匹配的次数为 L2,一共 匹配 L1 - L2 + 1,故时间复杂度为 O(L1*L2),即:O(n*m) 。

二、PK 算法

1、基本信息

RK 算法的全称叫 Rabin-Karp 算法,是由它的两位发明者 Rabin 和 Karp 的名字来命名的。

该算法可以理解为 BF 算法的升级版。

设计思路大概为: BF 算法简单但是时间复杂度高,为了解决该问题,可以优化的地方是更改每次匹配时比对的内容,由之前的比对每一个字符改为比对双方的 hash 值,进一步优化 hash 值计算的方法从而降低查找的时间复杂度。

2、查找流程

(1)version 1

将主串拆分成(L1 - L2 + 1)个子串,计算每一个子串的 hash 值;计算模式串的 hash 值。最后用模式串 hash 值与主串的(L1 - L2 + 1)个子串的 hash 值进行对比,相同的即为字符串匹配。

(2)version 2

在版本 1 的思路下继续延伸,计算 hash 值时间依然较多,此处可以优化。可以将 26 个英文字母作为 0、1、2、3、……、25 数字,将字符串转成十进制数字,栗子:

字符串:gced,转换成数字:6 * 26 ^ 3 + 2 * 26 ^ 2 + 4 * 26 ^ 1 + 3 * 26 ^ 0 = 106915 ,暂称该数为神秘数。

上述每一个主串的子串以及模式串均计算出神秘数,对比神秘数即可完成字符串匹配。当然有 神秘数 冲突的情况,每次神秘数比对相同时可以再次对比下两个字符串。

(3)version 3

在版本 2 中,每次计算神秘数的过程依然可以优化,如下所示:

假设主串为 gcedb

字符串:gced,转换成数字:6 * 26 ^ 3 + 2 * 26 ^ 2 + 4 * 26 ^ 1 + 3 * 26 ^ 0

向后挪一位,得到字符串 cedb,转换成数字:2 * 26 ^ 3 + 4 * 26 ^ 2 + 3 * 26 ^ 1 + 1 * 26 ^ 0,

可以发现计算 cedb 的神秘数时,可以写成如下:26*(2 * 26 ^ 2 + 4 * 26 ^ 1 + 3 * 26 ^ 0) + 1 * 26 ^ 0,括号部分的值已经在计算 gced 神秘数的时候得到了,这样每次保存上一个神秘数的一部分计算结果省略了大量的计算过程,可以降低时间复杂度。

3、时间复杂度

一共 匹配 L1 - L2 + 1,故时间复杂度为 O(L1),即:O(n) 。

4、神秘数冲突

当神秘数冲突过多时,实际上 PK 算法就退化成了 BF 算法,因为要频繁的比对子串和模式串,加大的时间复杂度,所以如何计算神秘数是关键,上述的计算过程仅仅是其中之一的方法。

参考:极客时间《数据结构与算法之美》王争

这门课真心推荐,内容很经典、栗子很形象,里面还包含了很多面试题目。真是居家旅行必备良药。

(SAW:Game Over!)

数据结构与算法 / 字符串匹配 / BF、PK 算法相关推荐

  1. C++KMP算法字符串匹配(附完整源码)

    C++KMP算法字符串匹配 C++KMP算法字符串匹配完整源码(定义,实现,main函数测试) C++KMP算法字符串匹配完整源码(定义,实现,main函数测试) #include <iostr ...

  2. 字符串匹配(KMP 算法 含代码)

    主要是针对字符串的匹配算法进行解说 有关字符串的基本知识 传统的串匹配法 模式匹配的一种改进算法KMP算法 网上一比較易懂的解说 小样例 1计算next 2计算nextval 代码 有关字符串的基本知 ...

  3. C语言实现字符串匹配的Rabin-Karp算法(附完整源码)

    实现字符串匹配的Rabin-Karp算法 实现以以下相关接口 boyer moore博伊尔-摩尔搜索算法的完整源码(定义,实现,main函数测试) 实现以以下相关接口 void rabin_karp_ ...

  4. [算法系列之二十六]字符串匹配之KMP算法

    一 简介 KMP算法是一种改进的字符串匹配算法,由D.E.Knuth与V.R.Pratt和J.H.Morris同时发现,因此人们称它为克努特-莫里斯-普拉特操作(简称KMP算法).KMP算法的关键是利 ...

  5. kmp算法字符串匹配C语言实现

    kmp算法字符串匹配 在leetcode做题时,有道题就是写一个strstr函数,先用思路最简单的直接两个循环做,提示时间超过限制.就查了查kmp的资料 翻了下算法导论,感觉像在看数学书,看不太懂,最 ...

  6. php随机匹配算法,字符串匹配的KMP算法+PHP实现

    1. 前言 看了阮一峰的字符串匹配的KMP算法,写得很好,推荐看看. 不过我想自己写个例子描述一下这个算法,顺便写个PHP实现,于是有了这篇博文. 2. 概述 [来自维基百科] 字符串搜索算法 字符串 ...

  7. 【数据结构与算法】字符串匹配 BF算法 RK算法

    单模式串匹配 BF 算法和 RK 算法 BM 算法和 KMP 算法 多模式串匹配算法 Trie 树和 AC 自动机 一.BF 算法 1,BF算法是Brute Force的缩写,中文译作暴力匹配算法,也 ...

  8. 数据结构-数组-字符串匹配:Knuth-Morris-Pratt算法(详解附完整代码)

    字符串匹配 字符串抽象数据类型 字符串模式匹配 简单的字符串匹配 Knuth-Morris-Pratt算法 背景分析 失配函数 定义 实现方法 函数分析 KMP函数 实现方法 函数分析 失配信息的另一 ...

  9. 字符串匹配BF/RK/BM/KMP算法

    主串长度m,匹配串(模式串)长度n. 一.BF 强制算法比较,最容易想到的,时间复杂度O(m*n) 二.RK 计算出匹配串的哈希值,遍历主串,求每次对应位置相同长度的子串哈希值,比较两者是否相同. 若 ...

最新文章

  1. mapreduce将key相同的value结合在一起_个人理解Hadoop中MapReduce
  2. java利用intellij进行类型推断
  3. 网页益智游戏怎么制作_休息一下,或者:如何使用Java 12制作出色的益智游戏...
  4. 安装完补丁后是否需要服务器重新启动
  5. fatal error: stropts.h: 没有那个文件或目录
  6. graphpad做折线图_Graphpad Prism搞定折线和曲线图,so easy!
  7. 中国西北地区专题地图合集(高清)
  8. AOC显示器OSD已锁是什么意思?怎么解锁?
  9. 调试3G模块语音通话
  10. 微信卡片生成,微信分享链接卡片名片制作,无需认证服务号微信分享链接美化描述LOGO
  11. 对接中国银联刷卡支付系统架构小demo
  12. 解决类似 The word is not correctly spelled等pom文件拼写错误问题
  13. 安全教育平台登录显示服务器繁忙,安全教育平台登录失败是怎么回事 解决方法...
  14. 【渗透测试】VulnHub-Lord Of The Root: 1.0.1
  15. 成功人士成功秘诀的调查报告,拥有梦想至关重要
  16. 计算机专业对于未来的规划,对所学专业的认识及对未来的规划.doc
  17. matlab .m 返回值,MATLAB一个M文件的function返回值怎么在另一个M文件中的函数调用这个返回值?...
  18. Cause: com.microsoft.sqlserver.jdbc.SQLServerException: 关键字 'user' 附近有语法错误
  19. 做人最重要的是学会珍惜,爱情如此,人生又何尝不是呢?
  20. Educational Codeforces Round 90 (Rated for Div. 2)(D 思维 E 打表)

热门文章

  1. zookeeper在Dubbo中的作用
  2. vagrant学习笔记 - 基本命令的使用
  3. 1.1 - C#语言习惯 - 使用属性而不是可访问的数据成员
  4. 看微信了解MySQL及相关IT技术
  5. 在Cisco路由器上配置WCCP
  6. android:layout_gravity=end,Android中 layout_gravity和gravity的区别
  7. [十问] 软件基础知识
  8. java junit Assert断言用法示例: Assert.assertEquals(期望的结果,运算的结果)
  9. ubuntu21.04中文冒号变乱码问题解决
  10. 使用gparted live分区工具对VMware及ESXI(vsphere)虚拟机进行根目录扩容(可视化界面操作)