KMP:字符串的模式匹配算法
假设有字符串: 0 1 2 3 4 5 6 7 8
A: x y x y x y y x x
B: x y x y y
欲判断B是否是A的一个子串。从位置0开始比较,到位置4的时候y不等于x所以根据KMP算法要向右滑动B才能与A进行重新匹配。
传统的方式是将B的第一个字符与A的下一个字符(第一次失败后将B中的第0位置与A中第1位置进行比较)进行重新匹配。
KMP向右滑动B如何能保证不错过A中可能的匹配串呢?
就第一次匹配失败而言,虽然A中2,3两个位置的字符目前还不能成为匹配A的子串,但是当B向右滑动到位置2时与A中的子串完全匹配。注意哦,是完全匹配!这时A中2,3两个位置的字符最终成为匹配B串的一部分。所以说当第一次匹配失败的时候,可能A中匹配失败的子串(1,2,3,4)的末尾还有一部分是有价值的。KMP所做的就是要把这部分价值最大化,也就是找出最长的可能成为最终匹配串的一部分。
KMP可以保证A中相对于B起始位置前面的字符不可能成为最终于B相匹配的子串的一部分,因为KMP算法已经把它们都收刮一遍都没发现有价值的字符。可能有价值的字符只能出现在当前这趟匹配失败的字符。而这些字符中有价值的只能处于A中子串的末尾。所以KMP算法应运而生,虽然A的子串不与B匹配。但是可能与B起始的部分子串相匹配,最终可能就成为了最终匹配串的一部分了。所以B就向右滑动,看下有没有与A末尾相匹配的串。