KMP算法

简单的模式匹配算法

从主串S的第一个字符起,与模式串T的第一个字符比较,若相等,则继续逐个比较后续字符;否则从主串的下一个字符起,重新和模式串的字符比较;以此类推,直至模式串中的每一个字符依次和主串S中的一个连续的字符序列相等,则称匹配成功,函数值为与模式串T中第一个字符相等的字符在主串S中的序号,否则,称匹配失败,函数值为0。

KMP

若已匹配相等的前缀序列中有某个后缀正好是模式串的前缀,则可将模式串向后滑动到与这些相等字符对齐的位置,主串 i 指针无需回溯,并从该位置继续比较。

子串指针移动位数

可通过子串本身得到部分匹配值表(PM表)

移动位数 = 已匹配的字符数 - 对应的部分匹配值

Move = (j - 1)- PM [ j - 1]

每当匹配失败,就去找它前一个元素的部分匹配值

改进:

将PM表右移一位(第一个元素填 -1),哪个元素匹配失败,直接看自己的部分匹配值,得到 next 数组

Move = (j - 1)- next [ j ]

相当于将子串的比较指针 j 回退到

j = j - Move = j - ((j - 1)- next [ j ] )= next [ j ] + 1

改进:
将 next 数组整体 +1

此时

j = next [ j ]

当子串的第一个字符与主串发生失配时,跳到子串的 next [ j ] 位置重新与主串当前位置进行比较。

求 next 数组

三种情况:

  • 模式串第一个字符与主串当前字符不匹配, next [0] = 0
  • 若已匹配相等的前缀序列中有某个后缀正好是模式串的前缀,此时可以计算出当前字符不匹配时的下一次比较位置
  • 最坏情况,模式串第一个字符与主串第 i 个字符比较,next [ j ] = 1

小技巧

在手算next数组时,next [0] = 0,next [1] = 1,后面的再去依次分析

进一步优化:

若 j 和 next [ j ] 指向同一个字符,则需再次递归,将 next [ j ] 修改为 next [ next [ j ] ]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值