在写这篇文章之前参考了两篇文章,觉得写得很好,尤其是阮一峰写的KMP算法。
KMP算法的关键是它的next数组,利用next数组能够高效地确定在当前失配的情况下,应当将模式串移动多少位才能够避免不必要的匹配。
不必要的匹配
如图,如果当前目标串与模式串在D
处发生失配,传统方法是从模式串的开头位置重新移动,直到开头位置能够找到匹配的字符然后重新开始下一个匹配流程。但我们注意到在D
发生失配之前的AB
是能够被开头的AB
正常匹配,那中间那些测试就是冗余的做法。
一个基本原理
让算法知道在失配字符之前的最长前缀匹配信息,同时利用这个信息跳过已经被比较过的位置,继续后移模式串,以此来提高匹配效率。下面详细说明。
过程模拟
首先确定一个规则:把模式串移动到最新位置后,在失配位置之前的字符都需要与目标串中的字符匹配。
还是用刚才那张图,观察在失配字符D
之前有最长两个字符AB
能够与模式串的前缀相匹配,那么当前的移动位数应当是4。这样移动的理由是我可以保证忽略尽量多的无用匹配,而同时保证不丢失应该做匹配测试的所有可能位置。我们可以得出一个移动位数的通式:
移动位数=模式串已匹配的字