字符串匹配基础(上):如何借助哈希算法实现高效字符串匹配
字符串匹配算法:BF算法和RK算法,都是单模式串匹配算法,即一个串和另一个串进行匹配,BM算法和KMP算法是多模式串匹配算法,即一个串种同时查找多个串,分别是Trie树和AC自动机
RK算法是BF算法的改进,RK算法是如何借助哈希算法来实现高效字符串匹配的呢?
BF算法
暴力匹配算法,也叫朴素匹配算法
主串和模式串
在字符串A中查找字符串B,那A是主串,B就是模式串,把主串的长度记作n,模式串的长度记作m,因为是在主串中查找模式串,所以n>m
作为最简单、最暴力的字符串匹配算法,BF算法就是我们在主串中,检查起始位置分别是0,1,2……n-m且长度为m的n-m+1个子串,看有没有跟模式串匹配的
如果主串是“aaa……aaa”模式串是“aaaaab”,我们每次都对比m个字符,要对比n-m+1,最复杂的时间复杂度是 O ( n ∗ m ) O(n*m) O(n∗m)
BF算法时间复杂度虽然很高,但是是一个比较常用的字符串匹配算法:一:实际的软件开发中,模式串和主串的长度都不会太长,每次模式串和主串中的子串匹配的时候,当中途遇到不能匹配的字符的时候就停止了,不需要把m个字符都对比一下 二:朴素字符串匹配算法思想简单,不容易出错,有bug也容易暴露和修复
RK算法
RK算法是在BF算法的基础上改进的,对朴素字符串匹配算法改造,引入哈希算法,时间复杂度会降低
通过哈希算法对主串中的n-m+1个子串分别求哈希值,然后逐个与模式串的哈希值比较大小,如果某个子串的哈希值与模式串相等,说明对应的子串和模式串匹配了
此时 哈希算法的设计为:假设要匹配的字符串的字符集中只包含K个字符,我们可以用一个K进制数来表示一个子串,这个K进制数转化成十进制数,作为子串的哈希值。
要处理的字符串只包含a~z 26个小写字母,把这26进制来表示一个字符串,把a~
z这26个字符映射到0~
25这26个数字,a就表示0,b就是1,z就是25,在十进制的表示法中,一个数字的值是通过下面的方法计算的,对应到26进制,一个包含a到z这26字符的字符串,计算哈希值的时候,只需要把进位从10改成26即可
“ 657 ” = 6 ∗ 10 ∗ 10 + 5 ∗ 10 + 7 ∗ 1 “ c b a ” = " c " ∗ 26 ∗ 26 + " b " ∗ 26 + " a " ∗ 1 = 2 ∗ 26 ∗ 26 + 1 ∗ 26 + 0 ∗ 1 = 1353 “6 5 7” = 6 * 10 * 10 + 5 *10 + 7 * 1 “c b a ” = "c" * 26 * 26 + "b" * 26 + "a" * 1 = 2 * 26 * 26 + 1 * 26 + 0 * 1 = 1353 “657”=6∗10∗10+5∗10+7∗1“cba”="c"∗26∗26+"b"∗26+"a"∗1=2∗26∗26