言简意赅告诉你KMP算法的原理,不管你信不信,我信了

我们以一个非常简单的例子来开头,举例主串为abababc,模式串为abc,在我们进行匹配的时候第一次匹配的效果为
abababc
ababc(在c处产生失配)
按照朴素的匹配算法,我们应该将模模式串向右移1位然后继续匹配,如图下所示情形
a bababc
 ababc(以次类推,在产生失配的时候将模式串逐步向右移位,产生最坏O(N*M)的时间复杂度)
 让我们仔细来思考第一次产生失配的情形,在i=5(i为模式串中的顺序),j=5(j为模式串中的顺序)时产生失配。
 为了使模式串尽可能的避免不必要的匹配,我们来观察模式串ababc本身的性质,我们注意到i[1]i[2]和i[3]i[4]是相同的序列,那么我们可以想到因为i[1]-i[4]已经和j[1]-j[4]匹配成功那么我们可以将模式串向右移两位使得i[1]i[2]和j[3]j[4]对应,因为j[3]j[4]是已经和i[3]i[4]匹配成功了的,所以我们可以这么做。
 但是我们为什么会直接将模式穿向右移两位呢?我们是根据i[1]i[2]和i[3]i[4]相同这一结论,由此我们想到是不是因为在i[1]i[2]和i[3]i[4]是两位匹配所以模式串就会向右移位2位呢?我们来举下一个例子,设主串为abcabcabcd,模式串为abcabcd,第一次匹配失败时情况为
 abcabcabcd
 abcabcd(d处产生失配)
 那么我们应用KMP算法,观察到在模式串中i[1]-i[3]和i[4]-i[6]相同,所以我们试着将模式串向右移动3位,此时匹配成功。
 据此我们得出结论在产生失配的时候,我们可以应用已经匹配部分的信息,直接将模式串向右移位较大的位数,来减少不必要的匹配,节省时间,由此我们引入next[]数组的概念,next[a]=k 这个表达式的意思是,当在模式串的第a个位置出产生失配时,将整个模式串向右移位k个长度,由我们在以上的举例可以知道,即i[1]-i[k]是和i[a-k+1]-i[a-1]相同的,所以我们在进行匹配之前可以先对模式串本身求出它的next数组来减少我们的任务。
 

你可能感兴趣的:(算法,KMP)