KMP算法初步学习

用途

  KMP算法:它是用来匹配字符串的,对于文字的检索和查找有很大的用处。说白了,它就是用来查看一个字符串中是否包含有另外一个字符串,如果有,则返回第一个字符的位置,否则返回-1,表示没有找到。

简单介绍

  1. 当然,除了KMP匹配算法,还有普通的字符串匹配算法,但是它的效率太低了,而KMP算法则是进一步对普通方法的改进,可以显著提高字符串的匹配效率。首先先来介绍一下普通的字符串匹配方法,通过比较来发现普通算法和KMP算法的不同。
  普通匹配方法的基本思想是:让模式串的第一个字符与主串的第一个字符比较,如果相等,则继续比较后面的字符。如果和主串的第一个字符就不相同,则继续用模式串的第一个字符和主串的第二个字符比较。这样看起来似乎很合理,但是,如果模式串的前几个字符都匹配成功,在后续字符的比较中有不同的,则下一次的比较,模式串仍然要回到第一个字符,再去和主串比较。
  下面用一个例子来说明一下:
这里写图片描述
  可见,这时比较到第三个字符的时候,出现了不同。
这里写图片描述
  而下一次的比较中,模式串依然从第一个字符开始和主串的第二个字符比较。
  如果主串的长度为n,模式串的长度为m,则普通算法的最坏时间复杂度为O(n*m)。

  2. 而KMP算法则使得模式串不用每次都回到第一个字符,它会利用之前已经比较过的字符,从而确定下次比较从第几个字符开始。
  KMP算法的核心就是确定每次匹配不成功时,下次比较开始的位置。
  那么怎么确定这个位置呢?它是和匹配不成功时,所在字符的位置有关的。这个位置就是所在字符之前的所有字符的 前缀和后缀 的最大相同长度。拿上面的例子来说,下次的开始的比较位置和模式串中下标0~2的字符有关。
  什么是前缀和后缀的最大相同长度呢?在这之前,要先明白前缀是什么?前缀就是一个字符串的前n个字符(0 < n < 字符串的长度),即不包括它自身。比如:abababb的前缀有:a、ab、aba、abab、ababa、ababab。后缀的意思和前缀相反。前缀和后缀的最大相同长度就是,先找出所有相同的前缀和后缀,然后取其中长度最长的那一组。
  比如:拿ababa来举例,ababa中前缀有:a、ab、aba、abab;后缀有:a、ba、aba、baba。那么前缀和后缀相同的有:a和aba,但是最大相同长度是aba。
  明白了什么是前缀和后缀的最大相同长度后,我们用next数组来记录这个位置。即先求出模式串中所有子串的前缀和后缀最大相同长度。

next数组    模式串中与数组(下标)对应的下标之前的字符     前缀和后缀的最大相同长度
next[0]null-1
next[1]a0
next[2]ab0
next[3]aba1
next[4]abab2
next[5]ababa3
next[6]ababab4

  还拿普通算法的例子来看一下,KMP算法是如何匹配的:
这里写图片描述
这里写图片描述
可以发现,KMP算法的下次比较位置不是0,而是1,而1也正是next[3]中所存的数。

小结

  利用改进的KMP算法可以显著提高字符串的匹配效率。这篇博客只是我对于KMP算法的一个初步理解,只是简单的介绍了KMP算法的基本思想,如果哪里有不正确的地方,还请各位大神指出。对于代码我还会继续学习的,KMP算法就简单介绍到这儿,感谢您的阅读。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值