我正在学习字符串搜索算法,并了解它们如何工作,但还没有找到关于在哪种情况下Rabin-Karp算法比KMP或Boyer-Moore更有效的答案。我看到它更容易实现,不需要相同的开销,但是除此之外,我毫无头绪。
那么,什么时候Rabin-Karp会比其他更好?
答案 0 :(得分:2)
这些算法中的每一个都有几个属性,可能会使它们在不同情况下是理想的或不良的。这是一个简短的摘要:
Rabin-Karp的一个主要优点是它使用O(1)辅助存储空间,如果您要查找的模式字符串很大,则该空间很大。例如,如果要查找长度为10 9 的较长字符串中所有出现的长度为10 7 的字符串,则不必分配10 <失败功能或移位表的sup> 7 机器字是一个主要的胜利。 Boyer-Moore和KMP都在长度为n的模式字符串上使用Ω(n)内存,因此Rabin-Karp在这里将是一个明显的胜利。
类似地,如果您要查找模式字符串出现多次的所有匹配项,则Rabin-Karp速度很慢。例如,如果要在包含10个字母{{sup> 9 个副本”的文本字符串中寻找10个字母a
的10 5 个副本的字符串1}}和Rabin-Karp,然后会有很多斑点出现在图案串上,并且每个斑点都需要进行线性扫描。这也可能导致运行时间为Ω((m + n-1)n)。
许多Boyer-Moore实现都有第二条规则,但在第一种情况下不会有不良的运行时。而且KMP没有这样的病理性最坏情况。
Boyer-Moore算法的一个优点是它不必扫描输入字符串的所有字符。具体来说,如果出现不匹配的情况,则可以使用“坏字符规则”跳过输入字符串的较大区域。更具体地说,Boyer-Moore的最佳运行时为O(m / n),这比Rabin-Karp或KMP所提供的运行时快得多。
假设您要搜索一组固定的多个文本字符串,而不只是一个。如果愿意,可以在字符串上多次运行Rabin-Karp,KMP或Boyer-Moore,以查找所有匹配项。但是,这种方法的运行时间不是很好,因为它随要搜索的字符串数线性扩展。另一方面,KMP很好地推广到了Aho-Corasick字符串匹配算法,该算法的运行时间为O(m + n + z),其中z是找到的匹配数,n是模式字符串的组合长度。请注意,这里不依赖于要搜索的不同模式字符串的数量!
答案 1 :(得分:0)
Rabin Karp 算法更好,该文本会发现多个模式匹配项,例如检测窃。
并且 Boyer Moore 会更好,当模式相对较大且字母大小适中且词汇量较大时。并且不适用于二进制字符串或非常短的模式。
同时, KMP 非常适合在较小的字母(例如生物信息学)中进行搜索或在二进制字符串中进行搜索。而且如果字母增加,运行速度也不会很快。
答案 2 :(得分:0)
这三个方面的时空复杂性(供参考) (用于查找所有出现的模式)
m:图案的长度
n:我们在其中搜索模式的字符串的长度
k:字母的大小
Rabin Karp:
O(1)辅助空间
使用散列来查找文本中模式字符串的完全匹配。它使用滚动哈希值快速筛选出与模式不匹配的文本位置,然后检查其余位置是否匹配
Boyer Moore:
最坏情况下的性能:Θ(m)预处理+ O(mn)匹配
最佳情况下的性能:Θ(m)预处理+Ω(n / m)匹配
最坏情况下的空间复杂度:Θ(k)。
可用于类似搜索的“ grep”。 https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string-search_algorithm#Performance
Knuth Morris Pratt:
最坏情况下的性能:Θ(m)预处理+Θ(n)匹配
最坏情况下的空间复杂度:Θ(m)
有关每种算法的更多详细信息,请查阅Wikipedia。