在Knuth-Morris-Pratt算法中,当“子串”字是相同字母的序列时,例如。 “AAAAAAAA ......”,失败表就像这样:“-1,0,1,2,3,4,5 ......”。
这意味着如果测试类似于“AAAAAAAB”当我们达到“B”时,我们将返回X字符并开始尝试再次匹配,尽管我们知道我们应该在B之后开始。
我错过了什么吗?
编辑(使示例具体):
让我们说测试是:AAAAAAAABAAAAAAAAA,即(8 As,B,9 As),找的是AAAAAAAAA,即(9 As)。
失败表将是:-1,0,1,2,3,4,5,6,7。
在某些时候它将是m = 0,i = 8.这将失败,因此m将变为m = m + i - T [8] = 0 + 8 - 7 => m = 1,我将是T [8] = 7.
这将再次失败,所以现在我们将m = 2,i = 6,然后m = 3,i = 7等。
答案 0 :(得分:2)
您将返回length(needle)
个字符,但只会在故障表给出的偏移处开始匹配。在这种情况下,如果有7个A而你在B上失败,T[7]
会说“跳过7个字符”,所以你检查needle[7]
与haystack[failed-length(needle)+7]
(失败的是索引)干草堆中针B中的A与A)相比较。因此它将以线性时间运行,总是跳过已经匹配的7个A中的6个的比较。一个更聪明的算法可能可以稍微跳过一点,但只有更多的常数,因为它不能比线性更好。