KMP算法及其应用

来源:互联网 发布:软件测试英文自我介绍 编辑:程序博客网 时间:2024/05/18 01:33

前言

今天学习了一个新算法:KMP算法
其实很久以前学过早忘了
KMP算法是用于处理字串问题的算法。

参考Matrix67的博客:KMP算法详解|Matrix67

KMP算法的原理

假设有字符串A和B,要求判断B是否是A的字串
其实就是对于每个i,求最大的j,使得Aij+1iB1j一一匹配
能匹配j指针就往后跳一个
否则就需要往回退
如下图:
这里写图片描述
我们希望往回退得越少越好,
通过上图可以发现,其实最佳方案就是 最长相同前后缀
对字符串B的每个前缀字串,找一个最长的长度l,使得长度为l的前后缀相同
这个可以预处理出来,第i个前缀的长度l记为next[i]
那么每次不匹配就往回退next[j]即可
只要出现j==m的情况就说明B是A的字串

代码如下:

for (int i=1,j=0;i<=n;i++){    while (j>0&&B[j+1]!=A[i]) j=nxt[j];    if (B[j+1]==A[i]) j++;    if (j==m){        //do something……    }}

下面来说预处理的事。
怎样得到next[]?假设已经得到next[1~i-1],现在求next[i]
设next[i-1]为j,如果B[j+1]==B[i],那么next[i]=next[i-1]+1
否则需要缩小j的范围。
这里写图片描述
有读者可能会发现,寻找next[i]的过程其实就是将B[1~i-1]与B[]匹配的过程
所以回退next[j]即可

代码如下:

nxt[1]=0;for (int i=2,j=0;i<=n;i++){    while (j>0&&B[j+1]!=B[i]) j=nxt[j];    if (B[j+1]==B[i]) j++;    nxt[i]=j;}

接下来证明复杂度。
通过上面的代码可以发现,j指针最多向后跳n次
而j在任何时候都是大于0的,所以回退也是O(n)级别的
所以KMP算法的复杂度是O(n)

KMP算法的应用

通过next[]数组,可以得到一个字符串的最小周期以及最小循环节
最小周期为n-next[n],如果周期能整除n,最小循环节就是周期
否则是n

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 网商银行人脸识别失败怎么办 电脑网页上的字变小了怎么办 把光驱换成固态硬盘后不识别怎么办 相机内存卡电脑读不出来怎么办 sd卡在电脑上无法格式化怎么办 内存卡突然读不出来了怎么办 怀孕两个月胎儿死在腹中怎么办 香港公司在大陆卖地皮资金怎么办 结婚证上的身份证号码错了怎么办 身份证快过期了人在外地怎么办 邮政电话银行登录密码忘记了怎么办 如果欠了3w不敢和家里说怎么办 大四学生欠了3w该怎么办 房子付了首付贷款贷不下来怎么办 浙江嵊泗人在金华丢了身份证怎么办 一证5号够了怎么办新卡 微信号被盗实名认证是自己的怎么办 苹果微信登录显示被盗风险怎么办 在诈骗公司上班被公安抓了怎么办 在国外护照不小心撕坏了怎么办 在俄罗斯护照超期拉黑应该怎么办 俄罗斯五年定居护照丢了怎么办 百家号文章质量分一直在下降怎么办 如果在韩国把护照弄丢了怎么办 坐亲戚的车出了车祸受伤怎么办 出了车祸受伤对方不拿医药费怎么办 如果找你买保险的不在了保单怎么办 赴美生子父母一方是绿卡怎么办 农保报销需要居住证过期了怎么办 有上海户口但没有户口本怎么办护照 签证用的旧护照丢失了英签怎么办 买的动迁房房东不肯过户怎么办 身份信息在qq邮箱泄露了怎么办 别人用我的身份证贷款不还怎么办 做兼职被骗了身份证泄露了怎么办 qq绑定的手机号被别人换了怎么办 银行卡丢失不知道卡号和密码怎么办 美团景点门票过了退款期怎么办 我的手机汽车之家无法看视频怎么办 来事泡温泉细菌感染外阴瘙痒怎么办 西澳大学语言班没通过怎么办