博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
字符串算法①——kmp
阅读量:5745 次
发布时间:2019-06-18

本文共 1290 字,大约阅读时间需要 4 分钟。

kmp算法是用来找A字符串的子串B的出现次数和位置的一种算法;

在看后面之前先看一个链接https://kb.cnblogs.com/page/176818/

然后对算法就有个大概的理解

 

为了实现这种算法我们需要一个next数组,也就是刚才链接里的部分匹配表,next[i]表示‘B中以i结尾的非前缀子串’与’B的前缀‘能够匹配的最长长度;

如:abababaac的i=7 为结尾的’非前缀子串‘有6个,分别是2~7,3~7,4~7,....,7~7;

如B【2~7】=’bababa‘与前缀’ababab'不匹配

   B【 3~7】=‘ababa’与前缀‘ababa'匹配,长度为5;

.............

得出next【7】=5;

但如何求出next数组我们可以假设next【1~6】已经被求出。next【6】=4;及B【3~6】与B【1~4】匹配;

接下来,B【7】=B【5】=’a',所以B【7】=5;皆大欢喜,下一个匹配了;

但当next【8】时,B【8】=‘a'   B【6】=’b'不匹配;

所以我们只好把匹配长度缩短;就是说上面我们以i=7结尾的匹配长度出了5之外,还有B[5~7]于B【1~3】的长度为3的匹配;B【1】于B【7】的长度为1的匹配;

我们尝试这两种匹配能否使i=8时匹配;

但B【8】于B【4】,B【2】不相等,所以我们只能让i=8从头开始匹配,B【1】恰好于B【8】匹配;所以next【8】=1;

单我们是如何记录5,3,1这些匹配长度的?

首先next【7】=5;说明从i=7往前5个字符于B【1~5】是相等的。

这是我们定义一个j;使从5往前j个字符与B【1~j】匹配;什么意思,就是以5为next【5】;(别忘了next数组定义);

当j=next【5】=3之后,下一个要找的就是next【3】;

所以代码就有了(可能还没有,看看代码就会了)

1.初始化next【1】=j=0,假设next【1~i-1】都求出,正在求next【i】。2.尝试匹配下一位,若果匹配失败,就令j=next【j】(上面讲了为什么)。直到j=0;3.若果匹配,就令j+1,next【i】=j;next[1]=0;for(int i=2,j=0;i<=strlen(a);++i){    while(j>0 && a[i]!=a[j+1]) j=next[j]; ////匹配失败    if(a[i]==a[j+1]) j++;      /// 匹配成功    next[i]=j;}

然后有了next数组就可以kmp了

for(int i=1,j=0;i<=strlen(b);++i){    while(j>0 && (j==n || b[i]!=a[j+1])) j=next[j];    if(b[i]==a[j+1]) j++;    if(j==strlen(a)) ///此时匹配  位置为i-strlen(a)+1}

然后就没了;

转载于:https://www.cnblogs.com/AidenPearce/p/8456005.html

你可能感兴趣的文章
webpack+typescript+threejs+vscode开发
查看>>
python读excel写入mysql小工具
查看>>
如何学习区块链
查看>>
搜索问题的办法
查看>>
微信分销系统商城营销5大重点
查看>>
求职准备 - 收藏集 - 掘金
查看>>
htm5新特性(转)
查看>>
Linux-Centos启动流程
查看>>
php 设计模式
查看>>
后端技术精选 - 收藏集 - 掘金
查看>>
Laravel 服务容器
查看>>
mac安装kubernetes并运行echoserver
查看>>
多页架构的前后端分离方案(webpack+express)
查看>>
算法(第4版) Chapter 1
查看>>
前端技术选型的遗憾和经验教训
查看>>
“亲切照料”下的领域驱动设计
查看>>
SRE工程师到底是做什么的?
查看>>
解读:Red Hat为什么收购Ansible
查看>>
Ossim下的安全合规管理
查看>>
DelphiWebMVC框架下BPL热部署实现
查看>>