字符串相关算法

本文介绍了字符串的前后缀公共子串概念,以及两种字符串匹配方法:朴素匹配和KMP算法。朴素匹配在失配时会回溯,而KMP算法通过预计算的next数组避免回溯,提高匹配效率。
摘要由CSDN通过智能技术生成

一、概念:

(1)最长前后缀公共子串:

字符串的一个前缀和一个后缀,如果它们相同,就被称为一个前后缀公共子串。特别地,我们定义最长前后缀公共子串不能是字符串本身。

eg:abcdabc->abc
aaaaaaa->aaaaaa

(2)字符串匹配:

模式匹配:子串的定位操作通常称为串的模式匹配。

目标串:主串S
模式串:子串P

匹配成功:若存在P的每个字符依次和S中的一个连续字符序列相等,则称匹配成功。返回P中第一个字符在S中的位置。
匹配不成功:返回-1。

二、字符串匹配:

1、朴素的字符串匹配:

如果当前字符匹配成功(即S[i]==P[j]),则i++,j++,继续匹配下一个字符。
如果失配(即S[i]!=P[j]),令i=i-(j-1),j=0。
相当于每次匹配失败后,我们让P在S中的起点变成下一个位置,然后重新进行匹配。

2、KMP算法:O(n+m)

利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。

核心思想:每次匹配过程中出现字符比较不等时,不回溯主指针i,利用已得到的部分匹配结果将模式串向右滑动尽可能近的一段距离,继续进行比较。

next:

定义失配函数next(j),表示当模式串中第j个字符与主串s[i]失配时,在模式串中可能和主串中s[i]匹配的字符的位置。
next数组和最长公共前后缀的关系:s[0…next[i]-1]与s[i-next[i]…i-1]是相同的。例如next[j]=k,代表s[0…k-1]与s[i-k…i-1]是完全一致的。所以可以认为next[i]表示了字符串s[0…i-1]的相同的前后缀的长度。next[0]=-1。

算法流程:

如果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-next[j],且此值大于等于1。

求next:

假设当前next数组中0~i-1个元素均已求出,现在求ne

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值