实例分析KMP字符串匹配算法

最近在力扣上遇到个字符串匹配的算法,解决的一些方法虽然简单,但是可以采用KMP字符串匹配算法来提高效率。具体题如下

给定两个字符串, A 和 B。

A 的旋转操作就是将 A 最左边的字符移动到最右边。 例如, 若 A = 'abcde',在移动一次之后结果就是'bcdea' 。如果在若干次旋转操作之后,A 能变成B,那么返回True。

示例 1:
输入: A = 'abcde', B = 'cdeab'
输出: true

示例 2:
输入: A = 'abcde', B = 'abced'
输出: false

注意:
    A 和 B 长度不超过 100。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/rotate-string

刚开始我采用的是直接匹配,但通过答案看出一些人用了KMP算法,下面就讲解一下KMP算法。

参考了视频讲解https://www.bilibili.com/video/BV1Px411z7Yo

如上图所示,要在字符串T中找到与字符串P相匹配的子序列

直接匹配的话,需要一个一个匹配,当匹配到p中第四个字符串b与T中的a不匹配时,p整体向后移一位,继续匹配,十分麻烦。

特别是遇到下列情况,此种情况下该算法最差。

KMP算法首先需要将待匹配的字符串的前缀都分别列出,然后把他们都当作独立的字符串。

然后分别找出这些字符串的最长前缀与最长后缀,举例如下图。

发现最长前缀和最长后缀不一样,然后需要将前缀和后缀的长度都分别减去一位,发现这时候前缀和后缀相匹配,都为ab。

将他们的公共最大前后缀分别列出

一般为零开始时,是不需要最后一段的,所以将最后一段刷去,并在最前面补一个-1。

将此列数字作为前缀表数字列出,并与待匹配字符串从前到后一一对应

然后讲此前缀表与要匹配的字符串对齐,并标出字母下标(字母下标都从0开始)。接下来准备开始匹配

当匹配到第四个字符不相同时,此时匹配失败,观察前缀表的数字为1。

将匹配字符串中的第1号位置的字符对准刚刚匹配失败且下标为1的字符,如下图所示

接下来从刚刚匹配字符串失败的位置继续匹配,发现依旧匹配不上,且此时下标为0

继续刚才过程,将待匹配字符串第0号位置与刚刚失败位置对齐

此时匹配成功,接下来往后进行匹配,发现匹配失败(c与a不对应),此时重复刚刚过程,继续寻找失败位置的前缀表下标,此时为0,并将第0号字符与它对齐

此时a与c不匹配,这时候前缀表为-1,就将待匹配字符串的第-1号对准(-1号并未在

字符串中,但可以通过前加表示),相当于往后平行一位。

此时-1位空白,没有东西,接着从下一位开始匹配

接下来就一一匹配,直到此时匹配成功!

但要注意的是,有时候一个字符串中可能会含有多个待匹配字符串,此时就将待匹配字符串中最后一位字符在前缀表中对应的字符开始继续执行该算法,如下图所示:

直到匹配完成,找出所有相匹配的字符串!

猜你喜欢

转载自blog.csdn.net/qq_44665418/article/details/105855228