字符串匹配基础(上)

  • 1.BF 算法的实现思想和应用
  • 2.RK 算法的实现思想和应用
  • 3.总结

单模式串匹配的算法,也就是一个串跟一个串进行匹配;
多模式串匹配算法,也就是在一个串中同时查找多个串;

1.BF 算法的实现思想和应用

BF 是 Brute Force 的缩写,中文叫作暴力匹配算法,也叫朴素匹配算法。
需要懂以下两个概念:
主串和模式串;

在字符串 A 中查找字符串 B,那字符串 A 就是主串,字符串 B 就是模式串。我们把主串的长度记作 n,模式串的长度记作 m。因为我们是在主串中查找模式串,所以 n>m。

BF算法的思想:

在主串中,检查起始位置分别是 0、1、2…n-m 且长度为 m 的 n-m+1 个子串,看有没有跟模式串匹配的;

这种算法最坏的情况时间复杂度为O(n*m);

虽然时间复杂度很高,但是在实际开发中,它却是一个比较常用的字符串匹配算法;原因如下:

第一,实际的软件开发中,大部分情况下,模式串和主串的长度都不会太长。而且每次模式串与主串中的子串匹配的时候,当中途遇到不能匹配的字符的时候,就可以就停止了,不需要把 m 个字符都比对一下。所以,尽管理论上的最坏情况时间复杂度是 O(n*m),但是,统计意义上,大部分情况下,算法执行效率要比这个高很多。
第二,朴素字符串匹配算法思想简单,代码实现也非常简单。简单意味着不容易出错,如果有 bug 也容易暴露和修复。在工程中,在满足性能要求的前提下,简单是首选。

2.RK 算法的实现思想和应用

RK 算法的全称叫 Rabin-Karp 算法,是由它的两位发明者 Rabin 和 Karp 的名字来命名的。 BF 算法的升级版。
对朴素的字符串匹配算法稍加改造,引入哈希算法,时间复杂度立刻就会降低。

RK算法思想:

过哈希算法对主串中的 n-m+1 个子串分别求哈希值,然后逐个与模式串的哈希值比较大小。如果某个子串的哈希值与模式串相等,那就说明对应的子串和模式串匹配了。因为哈希值是一个数字,数字之间比较是否相等是非常快速的,所以模式串和子串比较的效率就提高了。

通过哈希算法计算子串的哈希值的时候,需要遍历子串中的每个字符。尽管模式串与子串比较的效率提高了,但是,算法整体的效率并没有提高。采取以下方式来进行哈希算法的设计:

假设要匹配的字符串的字符集中只包含 K 个字符,我们可以用一个 K 进制数来表示一个子串,这个 K 进制数转化成十进制数,作为子串的哈希值。
比如要处理的字符串只包含 a~z 这 26 个小写字母,那我们就用二十六进制来表示一个字符串。我们把 a~z 这 26 个字符映射到 0~25 这 26 个数字,a 就表示 0,b 就表示 1,以此类推,z 表示 25。

这种哈希算法有一个特点,在主串中,相邻两个子串的哈希值的计算公式有一定关系。

很容易就能得出这样的规律:相邻两个子串 s[i-1] 和 s[i](i 表示子串在主串中的起始位置,子串的长度都为 m),对应的哈希值计算公式有交集,也就是说,我们可以使用 s[i-1] 的哈希值很快的计算出 s[i] 的哈希值。

26^(m-1) 这部分的计算,我们可以通过查表的方法来提高效率。我们事先计算好 260、261、262……26(m-1),并且存储在一个长度为 m 的数组中,公式中的“次方”就对应数组的下标。当我们需要计算 26 的 x 次方的时候,就可以从数组的下标为 x 的位置取值,直接使用,省去了计算的时间。

整个 RK 算法包含两部分,计算子串哈希值和模式串哈希值与子串哈希值之间的比较。
第一部分,可以通过设计特殊的哈希算法,只需要扫描一遍主串就能计算出所有子串的哈希值了,所以这部分的时间复杂度是 O(n)。
模式串哈希值与每个子串哈希值之间的比较的时间复杂度是 O(1),总共需要比较 n-m+1 个子串的哈希值,所以,这部分的时间复杂度也是 O(n)。
K 算法整体的时间复杂度就是 O(n)。

3.总结

BF 算法是最简单、粗暴的字符串匹配算法,它的实现思路是,拿模式串与主串中是所有子串匹配,看是否有能匹配的子串。所以,时间复杂度也比较高,是 O(nm),n、m 表示主串和模式串的长度。不过,在实际的软件开发中,因为这种算法实现简单,对于处理小规模的字符串匹配很好用。
RK 算法是借助哈希算法对 BF 算法进行改造,即对每个子串分别求哈希值,然后拿子串的哈希值与模式串的哈希值比较,减少了比较的时间。所以,理想情况下,RK 算法的时间复杂度是 O(n),跟 BF 算法相比,效率提高了很多。不过这样的效率取决于哈希算法的设计方法,如果存在冲突的情况下,时间复杂度可能会退化。极端情况下,哈希算法大量冲突,时间复杂度就退化为 O(n
m)。

字符串匹配基础(上)相关推荐

  1. 数据结构与算法之美 32 字符串匹配基础(中):如何实现文本编辑器中的查找功能

    如何实现文本编辑器中的查找功能 背景 BM 算法的核心思想 BM 算法原理分析 1. 坏字符规则 2. 好后缀规则 BM 算法代码实现 背景 文本编辑器中的查找替换功能,我想你应该不陌生吧?比如,我们 ...

  2. 【字符串系列】字符串匹配中的位并行算法

    [字符串系列]字符串匹配中的位并行算法 最近一段时间看了一点"柔性字符串匹配", 发现位并行算法在字符串匹配这个领域还是很有用的, 下面抒发一下鄙见. 首先, 字符串位并行算法在a ...

  3. 算法五——字符串匹配(上)

    文章内容.图片均来自极客时间. 如何借助哈希算法实现高效字符串匹配 1 概念和用途 字符串匹配:查找一个字符串A在字符串B中是否出现,这个过程就是字符串匹配.A称为模式串,B称为主串.主串的长度记为n ...

  4. 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 H题 Rock Paper Scissors Lizard Spock.(FFT字符串匹配)...

    2018 ACM-ICPC 中国大学生程序设计竞赛线上赛:https://www.jisuanke.com/contest/1227 题目链接:https://nanti.jisuanke.com/t ...

  5. linux下匹配字符串,linux上强大的字符串匹配工具详解-grep

    1. grep 是什么 grep 是用于匹配输入数据中符合条件的字符串的工具,其匹配过程支持正则表达式,因而匹配能力非常强大. grep 可以从文件或者标准输入设备中读取数据,若不指定任何文件名称,或 ...

  6. 字符串匹配shiftand算法

    令人惊叹的Shift-And/Shift-Or 写在前面:Shift-And/Shift-Or是如此令人惊叹的算法,在KMP基础上开始一段神奇之旅. 目的:以Shift-And算法为载体,试图在减少思 ...

  7. 【NLP】基于TF-IDF和KNN的模糊字符串匹配优化

    作者 | Audhi Aprilliant 编译 | VK 来源 | Towards Data Science 在处理真实数据时,最大的问题主要是数据预处理. 匹配可能是许多分析师面临的最大挑战之一. ...

  8. [JAVA][算法] [字符串匹配]KMP

    我们为什么需要KMP? 在字符串匹配问题中,我们需要找到匹配串pattern在原串text中的位置,一种显而易见的思路就是暴力匹配,如图所示,我们把pattern放置到text中的每个位置进行比较即可 ...

  9. 一招解决4道leetcode hard题,动态规划在字符串匹配问题中的应用

    全文共2869个字,6张图,预计阅读时间15分钟. 在做leetcode的时候,遇到hard题大家往往都觉得头疼,但其实,掌握方法,举一反三,hard题有时候我们也能想到好的思路,顺利攻破,今天我们就 ...

最新文章

  1. iPhone开发:抢先拥抱软件开发的未来
  2. python采用函数式编程模式吗_Python函数与函数式编程
  3. TypeScript reflect-metadata 结合方法装饰器实现的一个自定义语法检查的例子
  4. PHP Fatal error: Uncaught think\\exception\\ErrorException: error_log相关解决方法
  5. android_secure写权限,android.permission.WRITE_SECURE_SETTINGS权限报错
  6. [程序猿感悟] [悟] 两篇不错的文章 (转载自 stay4it )
  7. k8s pod里访问不到外部ip_安全公告:影响所有K8s版本的设计缺陷
  8. vue使用国密(sm2)
  9. 圆孔夫琅禾费衍射MATLAB程序,模拟夫琅禾费衍射的matlab源代码
  10. Data Shapley: Equitable Valuation of Data for Machine Learning(翻译)
  11. 开启双重验证后无法登录Outlook桌面版的解决方法
  12. 水晶报表繁体转简体心得:之一 RPT文件篇
  13. 影像自动解译_遥感图像解译
  14. 学考计算机会考考点工作总结,高中生学业水平考试工作总结范文
  15. vue处理PDF文档流数据并实现PDF的预览以及打印功能以及处理PDF打印乱码问题
  16. 电脑和手机好用的播放器
  17. IBM云计算服务–CMS、SoftLayer
  18. EM78P153B封装SOP8单片机方案IC开发
  19. 用友U8cloud智能财务精细管控
  20. 硬件描述语言基本知识

热门文章

  1. 什么是面向切面编程(aop)
  2. 二.字符设备驱动基础
  3. linux中d4B什么意思,Linux中环境变量文件及配置+++
  4. geth共识替换方法
  5. java 判断二维数组是否为空
  6. 为什么 c++ 比 java 运行的速度快
  7. 【2020】排队打饭(模拟)
  8. Java 53个关键字整理(自用版)
  9. Android之屏幕适配方案
  10. Opencv读取文件夹连续图片,RGB分量显示,图像灰度化