字符串匹配与AC自动机

解决字符串匹配问题,初级的算法是如下的BF算法:

从主串的第1个字符起和模式串的第一个字符比较,若相等,则继续逐个比较后续字符,否则从主串的第2字符起重新和模式串的字符比较。依次类推,直到模式串t中的每个字符依次和主串s中的一个连续的字符序列相等,则匹配成功。否则匹配不成功。如果文本串的长度为n,模式串的长度为mBF算法最好情况下的时间复杂度是O(n+m),最坏情况下的时间复杂度是O(nm)。后来又出现了一系列时间复杂度更低的算法,如KMP算法。

一、KMP算法

所谓KMP算法,其基本思路就是:

假设现在文本串S匹配到 i 位置,模式串P匹配到 j 位置,如果j = -1,或者当前字符匹配成功(即S[i] == P[j]),都令i++j++,继续匹配下一个字符;如果j != -1,且当前字符匹配失败(即S[i] != P[j]),则令 i 不变,j = next[j]。此举意味着失配时,模式串P相对于文本串S向右移动了j - next [j] 位。

换言之,当匹配失败时,模式串向右移动的位数=失配字符所在位置 - 失配字符对应的next 值,即移动的实际位数为j,且此值大于等于1

next 数组各值的含义:代表当前字符之前的字符串中,有多大长度的相同前缀后缀。例如如果 next [j] = k ,代表 j 之前的字符串中有最大长度为 k   的相同前缀后缀。这也意味着在某个字符失配时,该字符对应的 next 值会告诉你下一步匹配中,模式串应该跳到哪个位置(跳到 next [j] 的位置)。如果 next [j] 等于 0 -1 ,则跳到模式串的开头字符,若 next [j] = k k > 0 ,代表下次匹配跳到 j 之前的某个字符,而不是跳到开头,且具体跳过了 k 个字符。

步骤:



综上,KMPnext 数组相当于告诉我们:当模式串中的某个字符跟文本串中的某个字符匹配失配时,模式串下一步应该跳到哪个位置。如模式串中在j 处的字符跟文本串在i 处的字符匹配失配时,下一步用next [j] 处的字符继续跟文本串i 处的字符匹配,相当于模式串向右移动 j - next[j] 位。

优化:

p[j] != s[i] 时,下次匹配必然是p[ next [j]] s[i]匹配,如果p[j] = p[ next[j] ],必然导致后一步匹配失败(因为p[j]已经跟s[i]失配,然后你还用跟p[j]等同的值p[next[j]]去跟s[i]

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值