kcf算法中cos_window是什么意思_数据结构:KMP算法复习

KMP算法产生的背景:文本匹配问题

什么是文本匹配:在一个被称为主串的文本中,查找是否存在一个被称模式串的文本,比如你要在“今天是星期三”这样一个文本中,搜索“星期三”,这个问题看起来很傻,但它的应用很广泛,比如你在百度搜索信息的时候,就是在进行这样的文本匹配,只不过匹配次数非常多。

什么是KMP算法:一种高效的字符串(文本)匹配算法

为什么KMP算法高效:要理解这个,必须先了解一下什么是低效率的字符串匹配算法。

低效率的字符串匹配算法:朴素(暴力)字符串匹配算法,是一种简单,而又相对耗时的匹配算法,内容大概是:从主串的第一个字符开始,逐个的去和模式串进行对比,每当匹配失败,就返回主串的下一个字符,再开始匹配,直至主串结束。

Example:在主串aabcaaaac中寻找aaac

a98edd0e88cab59fef2876a8b6aac709.png

7b30b709c1792b48d64efb23cb123499.png

可以看出这是一个简单粗暴的方法

为什么朴素字符串匹配算法低效:因为它进行了很多回溯。

KMP算法是怎么运作的:要了解这个问题,首先我们要学习一下最长相等前后缀的概念

最长相等前后缀:一个字符串中,除去最后一个字符,前面任意长度的串,被称为前缀。除去第一个字符,后面任意长度的串,被称为后缀  

例如,12345这个串,它的前缀可以是 1 、12 、123、1234,它的后缀可以是5,45,345,2345。

最长相等前后缀就是前缀和后缀中相等且最长的那一个

例如ababab的最长相等前后缀是abab

233d3b19522e06d5834c89c45f942722.png

KMP算法是怎么减少回溯的:通过利用最长相等前后缀长度的概念。

next数组:每个值就意味着你在模式串的第n个位置匹配失败时,应该回溯到哪个位置。

如果下标初始值为0,Next[i]的值的意思是,当在下标为i的位置,即第i+1个字符发生匹配失败时,应该回到下标为next[i]的位置,即第next[i]+1个字符

如果下标初始值为1,Next[i]的值的意思是,当在下标为i的位置,即第i个字符发生匹配失败时,应该回到下标为next[i]的位置,即第next[i]个字符

example

66f19c8a42f9cc8000e872537828e38c.png

此时下标初试值为0,当你在模式串的第一个字符就匹配失败时,next值为-1,并不意味着你要把下标移到-1,根本就没有-1,而是要进行一个特殊操作:主串移到下一位,模式串移到第一个。

当你的模式串在第6个字符匹配失败时,也就是下标为5的位置,此时next[5]就意味着前5个字符的最长相等前后缀长度是3,同时也意味着你要把模式串的指针移到下标为3的位置,即第3+1个元素。

再来看看下标初始值为1是什么情况

0daa25a2eb7d33d75147da33dab690d8.png

此时下标初试值为1,当你在模式串的第一个字符就匹配失败时,next值为0,并不意味着你要把下标移到0,根本就没有0,而是要进行一个特殊操作:主串移到下一位,模式串移到第一个。

当你的模式串在第6个字符匹配失败时,也就是下标为6的位置,此时next[6]就意味着前6-1个字符的最长相等前后缀长度是3,同时也意味着你要把模式串的指针移到下标为4的位置,即第4个字符。

KMP算法高效的体现。

同样还是刚才的例子

3ad00c6363035fa2867f58e67ab783d8.png

59343a3750d1efbe2798bf25516f2ffc.png

虽然快的不多,但是依然比暴力算法少了三次比对。可见只有在主串存在存在比较多相似于模式串的情况下,Kmp算法才会比暴力算法快很多。

getnext算法例子1

e653cbf21251455feec171a233f16699.png

932f7832beb62c7ccee3b2b8157a29ca.png

19a6116f806f7cbf6b3b4c036085ad3d.png

例子2

6eb9862967d42df30001a73a5995b5af.png

805e1a9c33141adaa703275f158192a8.png

5c7fe678d82c8cff8ed59786b0dde201.png

6e82f0d664efc3137e3d8740d3dcd199.png

实际上KMP算法还存在缺陷

看如下例子

3a7eeaf43bae3b20a01371ab38be15b2.png

我们已知,主串当前是在c,且模式串当前不匹配位置是a,我们也知道模式串将会回溯到第二个位置,而第二个仍然是a,按道理来说没有对比的必要。

如何优化?采用nextval数组

做法  逐个检查 T[i]  与T[next[i]]的值是否相同,若相同,将next[i]的值置为next[next[i]]的值,若不相同,则保持原值

0c51db3821163175b677222ad76c08de.png

a421327d6fd0d1ffdc319021b0cb060c.png

573c641e51c1f0c927c3a77111fc6431.png

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值