免费建立网站软件,wordpress vs php的区别,做网站推广复杂吗,代理公司招标流程文章内容、图片均来自极客时间。
如何借助哈希算法实现高效字符串匹配
1 概念和用途
字符串匹配#xff1a;查找一个字符串A在字符串B中是否出现#xff0c;这个过程就是字符串匹配。A称为模式串#xff0c;B称为主串。主串的长度记为n#xff0c;模式串长度记为m。n查找一个字符串A在字符串B中是否出现这个过程就是字符串匹配。A称为模式串B称为主串。主串的长度记为n模式串长度记为m。ngt;mngt;mnm。 在java中有String的indexOf用就是字符串匹配。 字符串匹配有基础的BF算法、高效的KMP算法。
2 BF算法
BFBrute Force 暴力搜索 算法思想在主串中分别从起始位置012…n-m且长度为m的n-m1个子串是否和模式串相同。 从算法过程分析最坏时间复杂度是O(nm)。例如主串是“aaaa…aaa”(省略符号表示有若干个a)。模式串是aaaab。因为有n-m1个子串每次比较m次。比较总次数是(n−m1)∗mn∗m−m2m(n-m1)*mn*m-m^2m(n−m1)∗mn∗m−m2m记为O(nm)。 BF尽管时间复杂度比较高但在实际应用中经常使用。原因有二。 第一在实际应用中字符串都比较短每次两个字符串比较的时候遇到不相同的字符就可以提前返回。所以实际比n*m要少。 第二算法思想简单实现简单不容易出错。这也符合KISS(Keep it simple and stupid)原则。在工程中满足性能的前提下简单是原则。
3 RK算法
RKRabin-Karp是该算法的两位提出者。 在BF算法中两次字符串比较因为要比较m次复杂度较高。如果为每个字符串计算一个哈希值每次比较哈希值复杂度就可能会降低。 算法思想对模式串求哈希值。对n-m1个主串中的子串分别求哈希值然后逐个和模式串的哈希值比较。因为哈希值是一个数字比较非常快。但是因为求哈希所以整体算法效率没有提高。 改进可以通过改进求子串哈希值降低时间复杂度。假如字符串中只包含a-z这26个字母每个字母分别对应数字0~25。哈希值采用26进制表示。 例如quot;dbcquot;d∗26∗26b∗26c3∗26∗261∗2622056quot;dbcquot; d*26*26b*26c3*26*261*2622056dbcd∗26∗26b∗26c3∗26∗261∗2622056 这种哈希方法相邻子串哈希值是有特点的。可以使用前一个子串的哈希值计算下一个子串的哈希值。 记h1hash(dbc)326261262,h2hash(bce)126262264. A1262 B12626226 那么B26*A 令h[i-1]表示(i-1,im-2)子串的哈希值h[i]表示(i,im-1)子串的哈希值。那么 h[i](h[i−1]−26m−1(s[i]−′a′))∗26(s[im−1]−′a′)h[i](h[i-1]-26^{m-1}(s[i]-#x27;a#x27;))*26(s[im-1]-#x27;a#x27;)h[i](h[i−1]−26m−1(s[i]−′a′))∗26(s[im−1]−′a′) 这里还可以提高的地方时可以提前把26026^0260,26126^1261,…26m−126^{m-1}26m−1存入数组中。次方就是数组下标便于查询。
时间复杂度分析 计算哈希值主要扫描一遍主串即可时间复杂度O(n)。计算子串与模式串哈希值比较是否相同时间复杂度O(1)共需要n-m1次比较 时间复杂度O(n)。总体时间复杂度时间复杂度O(n)。
字符串很长哈希值超出能表示的范围怎么办 上面的设计完全没有哈希冲突当允许有哈希冲突会不会解决呢上面的算法是进位相乘如果改为加法数值就小很多了。例如quot;dbcquot;3126quot;dbcquot;3126dbc3126。这样的话取值范围小多了但哈希冲突概率会很高。如果每个字母不对应整数而是对应从小到大不同的素数这样哈希冲突的概率就会降低了。
如果有哈希冲突了怎么办 当两个字符串哈希值相同的时候就挨个字符串比较确保字符串真的相同。只是如果这样当冲突概率很高的时候RF比BF的效率还低。因为还要计算哈希。
4 思考题
上面讲的是一维字符串的比较如果是主串和模式串都是一个二维矩阵怎么匹配呢 解决思路可以将二维矩阵转为一个数组变成一维的再比较。