字符串匹配终结!(从暴力破解到KMP算法)

题目:给定一个字符串s = “aabaabaaf”,请在字符s中找到字符串c = “aabaaf”, 并且返回c在s中第一个字符的下标。
这道题是十分经典的字符串匹配问题。
首先我们的直觉解法就是暴力破解,步骤如下:

Round 1: aabaabaaf // 从上面字符串第一个字符a开始比对,发现f与b不相等
		 aabaaf 
Round 2: aabaabaaf // 从第二个字符a开始比对
		  aabaaf	
Round 3: aabaabaaf // 从第二个字符b开始比对
		   aabaaf	
.........
Round 4: aabaabaaf //匹配成功
			aabaaf

我们尝试从S第一个字符串开头,一一的比较每个字符。如果失败了,我们就从s的下一个字符串开始,重复该步骤。
假设s的长度是n,c的长度是m,那么时间复杂度就是O(n*m)。咋一看好像复杂度不高,但是实际生活中,s和c一般都很长,导致时间复杂度很大。所以我们来对暴力破解做一下优化,就是KMP算法
其实KMP算法就是暴力破解的思路上加一点巧思,但是这巧思真的很妙。
我们重新来看暴力破解算法:

Round 1: aabaa baaf
		 aabaa f

首先,字符串到b与f的时匹配不成功。这意味着,s的前五位和c的前五位是相同的。
然后,按照暴力破解的思想,s中的第一个a已经不可能是匹配成功的结果了。所以我们把第一个a剔除掉。

Round 2: a abaa baaf
		   aabaa f

其次,如果这时候匹配成功(以第二个a开头),就要求在剔除a后,剩下的字符可以相同。因为剔除了一个变成4个了,所以我们只能比对前四个。

Round 3: a abaa baaf
		   aaba a f

可以看到,如果以第二个a开头的话,就要求abaa与aaba要相等。但是显然这是不成立的。所以,我们继续从下一个字符b匹配,那么这时候,就要求

Round 4: aa baa baaf
		    aab a a f

我们看到,前面两个a是被我们剔除的,我们只需要比对b开头的三个字符。如上所示,第三个b也不可能是匹配结果的一部分。依次类推,我们可以得到

Round 5: aab aa baaf
		     aa b a a f

这时候,我们发现,s的aa与c的aa终于相同了。这意味着从第四个字符a可能是字符串的匹配的开头。请注意,仅仅是可能,但是我们通过这个方法,就可以直接排除掉第二个字符a和第三个字符b的开头的情况,从而减少了两次遍历。
KMP算法就是通过这个思想来减少遍历次数的!

这个思想是KMP算法的核心,来看看我们怎么提炼。
我们发现,其实我们要做的就是找出字符串aabaa去掉前面的字符,aabaa后面的字符后相等的情况

字符串:aabaa
a abaa
  aaba a
-------
aa baa
   aba aa
------
aab aa
	aa baa
------

所以我们只需要找到符合这个情况并把它记录起来,以后每一个匹配到aabaa后,如果f匹配不成功,我们就可以直接从aa后的位置匹配啦。
我们把这个记录到一个数组里,这

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值