KMP字符串匹配算法

KMP算法通过部分匹配表(next数组)避免无效移位,提高字符串匹配效率。算法核心在于计算next数组,当模式串与待匹配串不匹配时,通过next数组确定下次匹配起点。文章详细介绍了KMP算法思想、next数组的求解和优化以及线性匹配的实现。
摘要由CSDN通过智能技术生成

1. KMP算法基本思想

问题:在字符串ABABABACA中寻找字符串ABABACA,并返回第一次出现的位置。
下面分析匹配过程

ABABABACA
ABABACA
     |此处出现不匹配

若此时按照朴素字符串匹配算法进行匹配,模式字符串在不匹配的时候右移一位,重新从第一个字符进行匹配,情况如下

ABABABACA
 ABABACA
 |右移一位,重新从第一个字符进行匹配,很明显不匹配,无效偏移
ABABABACA
  ABABACA
  |再次右移一位,重新从第一个字符进行匹配,一直到模式串末尾,匹配成功

能否避免无效偏移和每次都从头开始匹配?这就是KMP算法所实现的。

ABABABACA
ABABACA
     |此处出现不匹配,将该位置记为pos
ABABABACA
  ABABACA
     |直接偏移2位
     |发现在上次出现不匹配的位置pos之前的3个字符ABA是匹配的,那么就不需要从模式串头开始匹配,直接从pos处进行匹配   

问题:ABABA和ABA是什么关系?怎么知道可以直接偏移2位?
ABA为字符串ABABA的前缀和后缀的最长的共有字符串。
ABABA的前缀字符串(不包括尾字符)有A AB ABA ABAB
ABABA的后缀字符串(不包括头字符)有A BA ABA BABA
所以ABABA的前缀和后缀的最长的共有字符串为ABA,长度为3

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

上述例子中,已匹配=5,部分匹配=3,所以移动位数=2

倘若算出每个位置的部分匹配值,就可以直接得到应该移动的位数,从而避免无效移位,这个要求的部分匹配值被称为部分匹配表(Partial Match Table)。

2. 如何求部分匹配表(next数组)?

next数组的前两个元素为-1,0

  A B A B A C A
 -1 0

求next[pos]要根据next[pos - 1]的值。

1. 当pos - 1处的字符与next[pos - 1]即cnd处字符相同时
如下图所示,浅蓝色是子串P[0..pos - 2]的最长前缀后缀公共字符串,并且两个深蓝色处字符相同,那么子串P[0..pos - 1]的最长前缀后缀公共字符串长度为next[pos - 1] + 1,即cnd + 1。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值