字符串匹配基础
字符串匹配算法有很多,首先讲一下BF算法和RK算法。RK算法是BF算法的改进,借助了前面讲的哈希算法来实现高效字符串匹配。
BF算法
BF算法是Brute Force的缩写,中文叫作暴力匹配法,也叫朴素匹配算法。首先要了解主串和模式串的概念。比如我们在字符串A中查找字符串B,则A为主串,B为模式串。若主串长度为n,模式串长度为m,则n>m。
BF算法作为最简单、最暴力的字符串匹配算法。在主串中检查起始位置分别是0、1、2、…、n-m且长度为m的n-m+1个子串,看是否有和模式串匹配。
最坏情况下,要比对n-m+1次,每次要比对m个字符。故最坏情况时间复杂度为O( n ∗ m n*m n∗m)。
尽管时间复杂度很高,但在实际开发中,它比较常用,因:
(1)实际开发中,主串和模式串都不会太长。匹配时,若中途遇到不能匹配的字符,就可以停止了。在大部分情况下,算法执行效率比O( n ∗ m n*m n∗m)要高得多。
(2)该匹配算法思想简单,代码实现也很简单。
def BF(a,b): #a为主串,b为模式串
n = len(a)
m = len(b)
for i in range(n-m+1):
for j in range(m):
if a[i+j]!=b[j]:
break
if j == m-1:
return i
if i == n-m+1:return -1
RK算法
在BF算法的基础上引入了哈希算法:通过哈希算法对主串中的n-m+1个子串分别求哈希值,然后逐个与模式串的哈希值比较大小。如果某个子串的哈希值与模式串相等,那就说明相应的子串和模式串匹配。因为哈希值是一数字,判断数字之间比较是否相等是非常快速的,因此比较效率就提高了。
不过提高哈希算法计算子串的哈希值时,需遍历子串中的每个字符。尽管比较的效率提高了,算法的整体效率并没有提高。
如何提高哈希算法计算子串哈希值的效率?这就需要哈希算法设计的有技巧。假设要匹配的字符串的字符集中只包含K个字符,可以用K进制数来表示一个子串。这个K进制数转化成十进制数,作为子串的哈希值。举个例子,比如要处理的字符串只包含a-z这26个小写字母,那就用二十六进制来表示一个字符串。把a-z映射到0-25这26个数字,