C语言实现KMP子串匹配查找

KMP查找

1.概述

KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n)。

2.算法

设主串与子串如下:

主串 a b c a b c e a b c a b c d a b c a b c f
子串 a b c a b c d a b c a b c f
  • 常见的字符串匹配:当主串与子串在逐字符匹配时一旦没有匹配成功,则让主串回跳到第一个位置重新开始比较,时间消耗很大。
  • 而KMP子串匹配:当某一位置匹配不成功时,主串不回跳使子串回跳,(但如果子串回跳到第一个位置,也会浪费一定的时间),KMP采用Next数组来解决这一问题。
Next数组的实现就需要引入字符串的前后缀

前缀:以当前串开头为开头的串,不能包括字符串本身。
后缀:以当前串结尾为结尾的串,也不能包括字符串本身。
最大匹配长度:前缀与后缀相等的最大字符个数。

试求出此字符串的前缀、后缀与前后缀最大匹配长度:ababa

前缀 a ab aba abab
后缀 a ba aba baba

由此可以看出此串最大匹配长度为3。

再回过头来看KMP匹配:

Next数组就是求子串的前后缀匹配最大长度
例如:

  • s2[0] a 前后缀最大匹配长度为:0
  • s2[1] ab 前后缀最大匹配长度为:0
  • s2[2] abc 前后缀最大匹配长度为:0
  • s2[3] abca 前后缀最大匹配长度为:1
  • s2[4] abcab 前后缀最大匹配长度为:2
  • s2[5] abcabc 前后缀最大匹配长度为:3
  • s2[6] abcabcd 前后缀最大匹配长度为:0

d和s2[13]:f 所面对的情况一样,肉眼很容易看出他的最大匹配长度为0,然而用代码实现并不是那么简单,你需要找到前一个字符所对应的Next数组,如果不为0你需要跳到它的Next数组所对应的s2的位置,如果为0你需要跳到子串开头位置,将此字符与其进行比较,如果都不相同,此时最大匹配长度才为0。

这么干说可能不太理解,用s2[6]='d’做例子。Next[5]=3,'d’则要和s2[3]='a’做比较,不相等。虽然s2[6]与s2[3]不相等,但他们所对应的前面的位置是相等的,设’d’现在所在位置为s2[3],Next[2]=‘0’,’d’则要和s2[0]='a’做比较,不相等,而s2也走到了字符串头的位置,这时才能说Next[6]=0,也就是说’d’所对应前后缀最大匹配长度为0

  • 后面情况类似…
下标 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
主串s1 a b c a b c e a a b c a b c d a b c f
子串s2 a b c a b c d a b c f
Next 0 0 0 1 2 3 0 1 2 3 0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值