数据结构与算法系列22--字符串匹配算法

字符串匹配这样的函数,在很多编程语言中都提供了字符串的查找算法,那它底层具体是怎么实现的呢?
字符串的匹配算法有很多,简单一点的:BF算法和RF算法。高级一点的,BM算法和KMP算法。

BF算法

BF算法全称是Brute Force,中文叫暴力匹配算法,也叫朴素匹配算法,该算法简单、好懂,但是性能不高。
思想:
我们在主串中,分别检测起始位置分别是0、1、2、…n-m且长度为m的n-m+1个子串,看有没有跟模式串匹配的(其中n为主串长度,m为模式串长度)
:主串为待检测的字符串,模式串为要查找匹配的串。假设要在字符串A中查找字符串B,那字符串A就是主串,字符串B就是模式串。
分析:
该算法是时间复杂度为O(m*n)。 虽然时间复杂度相对较高,但在实际的开发中,它却是一个比较常用的字符串匹配算法。因为实际的软件开发中,大部分情况下,模式串和主串的长度都不会太长。算法思想简单,代码实现也非常简单。

RK算法

RK算法的全称叫Rabin-Karp算法,是由它的两位发明者Rabin和Karp的名字来命名的。
思想:
通过哈希算法对主串中的n-m+1个子串分别求哈希值,然后逐个与模式串的哈希值比较大小。如果某个子串的哈希值与模式串的哈希值相等,那就说明对应的子串和模式串匹配了。因为哈希值是一个数字,数字之间的比较要比字符串之间的比较要快很多,所以模式串和子串之间的比较效率要提高了。
分析:
整个RK算法包含两部分,计算子串哈希值和模式串哈希值与子串哈希值之间的比较。第一部分计算子串哈希值是要先扫描一遍主串,然后计算出每个子串的哈希值,这部分的时间复杂度是O(n),第二部分模式串哈希值与子串哈希值之间的比较,总共需要比较 n-m+1 个子串的哈希值,所以,这部分的时间复杂度也是O(n),所以,RK算法整体的时间复杂度就是O(n)。

高级的BM算法

思想:
BM算法的匹配顺序比较特别,它是按照模式串下标从大到小的顺序,倒着匹配的。利用模式串本身的特点,在模式串中某个字符与主串不能匹配的时候,将模式串往后多滑动几位,以此来减少不必要的字符比较,提高匹配的效率。
BM算法构建的规则有两类,坏字符规则和好后缀规则。
坏字符规则:
我们从模式串的末尾往前倒着匹配,当我们发现某个字符没法匹配的时候。我们把这个没有匹配的字符叫作坏字符(主串中的字符)。我们拿坏字符在模式串中查找,如果发现模式串中并不存在这个字符,可以将模式串直接往后滑动m位,即坏字符后面的位置,然后再开始重新比较。但是坏字符规则向后滑动的步幅还不够大,于是需要好后缀规则。
好后缀规则
从后往前逐位比较模式串与主串的字符,当出现坏字符时停止。若存在已匹配成功的子串{u},那么在模式串的{u}前面找到最近的{u},记作{u’}。再将模式串后移,使得模式串的{u’}与主串的{u}重叠。若不存在{u’},则直接把模式串移到主串的{u}后面。为了没有遗漏,需要找到最长的、能够跟模式串的前缀子串匹配的,好后缀的后缀子串(同时也是模式串的后缀子串)。然后把模式串向右移到其左边界,与这个好后缀的后缀子串在主串中的左边界对齐。
BM算法,尽管它很复杂,也不好理解,但却是工程中非常常用的一种高效字符串匹配算法。

最知名的KMP算法

尽管在实际的开发中,我们几乎不大可能自己亲手实现一个KMP算法。但是,学习这个算法的思想,对我们开拓思维是有非常大的好处。实际上,KMP算法跟BM算法的本质是一样的。
KMP的全称是Knuth Morris Pratt,是根据三位作者(D.E.Knuth,J.H.Morris+和V.R.Pratt)的名字来命名的。
思想:
跟BM算法相似,假设主串是a,模式串是b。在模式串与主串匹配的过程中,当遇到不可匹配的字符的时候,我们希望找到一些规律,可以将模式串往后多滑动几位,跳过那些肯定不会匹配的情况。
具体过程看不太懂,只能先暂且略过了。
可以看下这篇文章写的http://www.cnblogs.com/c-cloud/p/3224788.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值