谈谈KMP算法

KMP算法的资料网上已经一大把了,主要用来解决某个文本片断是否包含另外一个子串问题。这里假设文本片断的长度n大于子串长度m,如:算法

文本串为ABCDABGHIJK指针

子串为   ABCDABE字符串

在传统的暴力解法中当子串的E与主串的G不匹配时,将文本串从B开始、子串从头开始从新匹配,这样的时间复杂度为(n-m+1)*m,很显然效率是比较低的。效率

KMP算法的思想是当子串的E不匹配时,文本串保持在G位置,子串从C位置开始匹,关键就是要知道:方法

一、为何是C这个位置?集合

二、如何求C这个位置?时间

先说第一个问题:直观的看是由于C前面的AB与G前面的AB正好可以匹中。但实际上就像采用暴力法解决时,本质上是在查找子串ABCDABE与剩余文本串BCDABGHIJK的第一个能找到子串最长前缀AB的位置,因为KMP算法不想让未匹中字符G的位置进行回溯即已经固定,因此就等价于查找子串ABCDABE与剩余文本串BCDAB的最长公共前缀问题。因为最长公共前缀是AB因此子串从C位置开始匹。字符

再说第二个问题:查找子串ABCDABE与剩余文本串BCDAB的最长公共前缀问题等价于计算子串ABCDA与剩余文本串BCDAB的最长公共前缀问题(由于最长公共前缀的长度必定是<=剩余文本串BCDAB的长度),所以也就等价于计算字符串ABCDAB的最长公共先后缀长度也就是计算集合(ABCDA、ABCD、ABC、AB、A)与集合(BCDAB、CDAB、DAB、AB、B)的交集中字符长度最长的字符即AB。

求解的方法比较简单将ABCDA与BCDAB比较、ABCD与CDAB比较、ABC与DAB比较、AB与AB比较、A与B比较便可。

实际上子串的每一个字符都要求出当不匹配时指针应该停留的位置,这个在匹配前须要进行预处理,预处理的方法就是求解第二个问题的方法。

相关文章
相关标签/搜索