算法导论字符串匹配—朴素算法Rabin-Karp有限自动机KMP

Posted 之墨_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法导论字符串匹配—朴素算法Rabin-Karp有限自动机KMP相关的知识,希望对你有一定的参考价值。

算法导论【字符串匹配】—朴素算法、Rabin Karp、有限自动机、KMP

朴素字符串匹配算法

  • 预处理时间0
  • 匹配时间O((n-m+1)m)



Rabin-Karp算法

  • 预处理时间Θ(m),需要预先算出匹配串的哈希值
  • 匹配时间O((n−m+1)m),匹配过程与朴素算法类似,但是不需要逐个比对,先比对哈希值,这样可以减少字符匹配次数,计算待匹配的m个字符的哈希值,采用特定方法可以只要常数时间
  • Rabin-Karp算法的预处理时间为 Θ ( m ) \\Theta(m) Θ(m),在最坏情况下,运行时间为 Θ ( ( n − m + 1 ) m ) \\Theta((n-m+1)m) Θ((nm+1)m)
  • Rabin-Karp算法比较字符串的哈希值,而不是字符串本身。为了提高效率,可以从当前位置的哈希值轻松计算文本中下一个位置的哈希
  • 简单说就是:每次计算m个字符的字符串的哈希值,然后与匹配串的哈希值对比,如果不相等那这两个字符串肯定不一样,如果哈希值相等,那么再逐个匹配字符,这样可以减少不必要的匹配
  • 如果哈希值不相等,算法将计算下一个M字符序列的哈希值。如果哈希值相等,算法将比较模式和M字符序列。这样,每个文本子序列只有一个比较,只有当哈希值匹配时才需要字符匹配
  • Rabin Karp算法的预处理阶段包括计算哈希 H a s h ( P ) Hash(P) Hash(P)。它可以在恒定的空间和 O ( m ) O(m) O(m)时间内完成。
  • 在搜索阶段,将哈希 H a s h ( P ) Hash(P) Hash(P)与哈希 H a s h ( T [ j . . j + m − 1 ] ) Hash(T[j..j+m−1]) Hash(T[j..j+m1])比较就足够了。如果找到了一个等式,仍然需要逐个字符检查等式 P = T [ j . . j + m − 1 ] P=T[j..j+m−1] P=T[j..j+m1]
  • Rabin Karp算法的时间复杂度为 Θ ( ( n − m + 1 ) m ) = Θ ( m n ) Θ((n−m+1)m)=Θ(mn) Θ((nm+1)m)=Θ(mn)(例如,当在n中搜索m时)。当有效点很小时,例如 O ( 1 ) O(1) O(1),其预期的文本字符比较数为 O ( n + m ) = O ( n ) O(n+m)=O(n) O(n+m)=O(n)

有限自动机

  • 预处理时间O(|mΣ|),|Σ|为待匹配串的字母表大小
  • 匹配时间Θ(n),预处理完后只需要扫描一遍字符串即可找到匹配串

KMP算法

  • 预处理时间Θ(m)

  • 匹配时间Θ(n)

  • 关键在于计算出前缀 π \\pi π数组, π \\pi π就是文本串中在该位置能够得到最长的前后缀长度,举个例子:

  • 预处理过程:- 匹配过程:

以上是关于算法导论字符串匹配—朴素算法Rabin-Karp有限自动机KMP的主要内容,如果未能解决你的问题,请参考以下文章

模式匹配:滚动哈希到 Rabin-Karp 算法

模式匹配:滚动哈希到 Rabin-Karp 算法

Python字符串查找算法之BMHBNFS算法

何时使用 Rabin-Karp 或 KMP 算法?

算法基础 - 朴素模式匹配算法、KMP模式匹配算法

Rabin-Karp指纹字符串查找算法