KMP算法 Next数组详解(【洛谷3375】KMP字符串匹配 )

				版权声明:本文为博主原创文章,未经博主允许不得转载。					https://blog.csdn.net/qq_30974369/article/details/74276186				</div><div id="content_views" class="markdown_views"><!-- flowchart 箭头图标 勿删 --><svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path></svg><h2 id="题面"><a name="t0" target="_blank"></a>题面</h2>

题目描述

如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置。

为了减少骗分的情况,接下来还要输出子串的前缀数组next。如果你不知道这是什么意思也不要问,去百度搜[kmp算法]学习一下就知道了。
输入输出格式

输入格式:

第一行为一个字符串,即为s1(仅包含大写字母)

第二行为一个字符串,即为s2(仅包含大写字母)

输出格式:

若干行,每行包含一个整数,表示s2在s1中出现的位置

接下来1行,包括length(s2)个整数,表示前缀数组next[i]的值。

输入样例:

ABABABC
ABA

输出样例:

1
3
0 0 1

说明

时空限制:1000ms,128M
数据规模:
设s1长度为N,s2长度为M
对于30%的数据:N<=15,M<=5
对于70%的数据:N<=10000,M<=100
对于100%的数据:N<=1000000,M<=1000

题解

这是一道KMP裸题(模板题。。)
我就是拿着它学习一下KMP算法
其实原来我学过KMP算法
但是一直没有弄懂next(跳转)数组是如何求出来的。
最近花了一个下午自己研究了一下KMP算法
现在终于觉得KMP很简单了~


现在直接说next数组把
至于有什么作用,next数组是干什么的,请自行百度,有很多dalao总结的非常到位,看一看就会明白。

好,来说next数组

这里写图片描述

并不用在意这一坨黑的是什么东西,我们就假设他是我们要求next数组的字符串。

next数组求的东西就是从起始位置到当前位置最长的相等的前缀和后缀的长度。
(举个例子China的前缀有:C、Ch、Chi、Chin、China ; 后缀有a、na、ina、hina、China)

这里写图片描述


我们继续,如上图红色的是当前位置(设为j)前,所匹配上的最长前缀和后缀,蓝色的是当前要匹配的位置。

这里写图片描述

那么,我们就拿当前位置和原来匹配到的最长前缀的后一位相比较
如果两个位置相同,
显然,
可以和前面的红色连在一起,
此时就有next[j]=next[j-1]+1

如果两个位置不相同,
根据next数组的性质,
显然的,你的当前的相等的前缀和后缀只能够继续向前找,
也就是说,你当前的next数组一定会减小。

这里写图片描述

既然前面的红色部分存在一小块灰色,那么,后面的红色部分也必然存在灰色部分。

这里写图片描述


所以,判断当前位置和前面那一块灰色的前缀的后一位是否相等。
如果这两位相同的话,不就可以和前面的灰色部分连在一起了吗

这里写图片描述

此时,又回到一开始的那一步。
因此,求解某个位置的next值是一个循环过程。
不断检查 上一位的 最长前缀的 后一位(i位置)(这句子有点拗口)
如果相等next[j]=next[i]+1
否则令 i=next[i-1]+1,继续循环匹配

如果没有看懂就自己多看几遍,自己找几个字符串算一算

所以:求解next数组的代码:

inline void GetNext(string s)//获得字符串s的next数组
{int l=s.length(),t;Next[0]=-1;//如果在0位置失配则是向下移动一位for(int i=1;i<l;++i)//依次求解后面的next数组{t=Next[i-1];while(s[t+1]!=s[i]&&t>=0)//循环求解next值 t=Next[t];if(s[t+1]==s[i])//如果是匹配上而退出循环 Next[i]=t+1;else            //否则则是匹配不上 Next[i]=-1; //指向头 }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15


代码很简洁的~
那么,接下来如何利用Next数组求解匹配
那就自己baidu吧(知道了next数组,KMP就很好理解了)

接下来贴上小蒟蒻的源码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
const int MAX=1001;
int Next[MAX];
vector<int> Ans;
inline void GetNext(string s)//获得字符串s的next数组
{int l=s.length(),t;Next[0]=-1;//如果在0位置失配则是向下移动一位for(int i=1;i<l;++i)//依次求解后面的next数组{t=Next[i-1];while(s[t+1]!=s[i]&&t>=0)//循环求解next值 t=Next[t];if(s[t+1]==s[i])//如果是匹配上而退出循环 Next[i]=t+1;else            //否则则是匹配不上 Next[i]=-1; //指向头 }
}
inline void KMP(string s1,string s2)
{GetNext(s2);int l1=s1.length();int l2=s2.length();int i=0,j=0;while(j<l1){if(s2[i]==s1[j])//当前位匹配成功,继续匹配下一位{++i;++j;if(i==l2)//完全匹配{Ans.push_back(j-l2+1);//储存答案i=Next[i-1]+1;//继续匹配                }}else{if(i==0)//在首位不匹配j++;//直接向后挪一位elsei=Next[i-1]+1;//跳转}}
}
int main()
{string s1,s2;int l;cin>>s1>>s2;l=s2.length();KMP(s1,s2);for(int i=0;i<Ans.size();++i)cout<<Ans[i]<<endl;for(int i=0;i<l;++i)cout<<Next[i]+1<<' ';cout<<endl;return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

最后再说一句
如果需要加深理解KMP的过程
请去SYC的blog看看他的gif动图
你可能就会有更多了解
膜拜SYC大佬去

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/549409.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

“顾问”

关于顾问的定义&#xff0c;有这么一个故事&#xff1a;一个客户花了大价钱启动了一个项目&#xff0c;这个项目主要解决的问题是&#xff1a;“现在几点了&#xff1f;”这时顾问走过来说&#xff1a;“请借你的手表用一下。”然后看了一下说&#xff1a;“现在是下午3点。”然…

转自知乎-我见过最通俗易懂的KMP算法详解

有些算法&#xff0c;适合从它产生的动机&#xff0c;如何设计与解决问题这样正向地去介绍。但KMP算法真的不适合这样去学。最好的办法是先搞清楚它所用的数据结构是什么&#xff0c;再搞清楚怎么用&#xff0c;最后为什么的问题就会有恍然大悟的感觉。我试着从这个思路再介绍一…

Sybase常见问题

1. Sybase数据库日志满碰到这种情况&#xff0c;常会出现能查询数据&#xff0c;但无法更新数据&#xff0c;启动事务等。在代码中跟踪可以发现&#xff0c;连接能够打开&#xff0c;但事务却无法开启。常会提示“Connection to Sybase server has been lost. All active trans…

Redis在Window服务下的安装

Redis 安装1.首先在Windows下下载安装Redis下载地址&#xff1a;https://github.com/MicrosoftArchive/redis/releases根据你电脑系统的实际情况选择32位还是64位&#xff0c;在这里我下载了的是Redis-x64-3.0.500.zip压缩包&#xff0c;压缩后得到解压文件.2.测试运行打开一个…

在一个禁止离婚的国家结婚

爱尔兰是全世界结婚率最低的国家&#xff0c;作为一个信奉天主教的国度&#xff0c;这个国家是禁止离婚的。很多适逢婚龄的男男女女大都选择观望&#xff0c;迟迟不去婚姻登记部门办理手续。所以&#xff0c;在爱尔兰流行不婚和晚婚。但一对中国夫妻在爱尔兰的结婚经历&#xf…

【计算机网络】时延、发送时延、传输时延、处理时延、排队时延、时延带宽积

版权声明&#xff1a;答应我&#xff0c;右上角点个「赞」再走好么&#xff5e;不甚感激&#xff5e;&#xff08;卖萌脸ヾ(^▽^)ノ https://blog.csdn.net/liuchuo/article/details/52893629 </div><link rel"stylesheet" href"https://csdnim…

ASP.NET (C#) 面试笔试题目收集

1. 简述 private、 protected、 public、 internal 修饰符的访问权限。 答 . private : 私有成员, 在类的内部才可以访问。 protected : 保护成员&#xff0c;该类内部和继承类中可以访问。 public : 公共成员&#xff0c;完全公开&#xff0c;没有访问限制。 internal: 在同一…

排队时延(Queuing delay)

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请注明出处。 https://blog.csdn.net/zhangskd/article/details/18224897 </div><link rel"stylesheet" href"https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-f57…

传播时延、发送时延、处理时延和排队时延各自的物理意义是什么?

传播时延、发送时延、处理时延和排队时延各自的物理意义是什么&#xff1f; 传播时延: 信号在传输通道上产生的时延 发送时延&#xff1a;以一定的速率发送完一个一定长度报文所需的时间 处理时延&#xff1a;节点进行报文存储转发处理所产生的时间 排队时延&#xff1a;报文…

爬山法实现 八皇后问题 (Python 实现)

本文主要简单阐述爬山法的基本算法思想&#xff0c;并给出用此算法实现八皇后问题详细过程 最基本的爬上搜索算法表示&#xff1a;(节选自《人工智能》第二版)&#xff1a; function HILL-CLIMBING(problem) return a state thate is a locak maximum inputs: problem …

系统容灾备份选型的决策表

冷备Master/SlaveMaster/Master两阶段提交Paxos一致性差最终一致性最终一致性强一致性强一致性事务不支持全局事务本地事务全局事务全局事务延迟低低低高高吞吐高高高低中等数据丢失概率很多很少很少不会丢失不会丢失Failover无只读读/写读/写读/写摘自对Google App Engine Dat…

至誠而不動者

至誠而不動者&#xff0c;未之有也&#xff1b; 吾學問廿年齡亦而立然未能解斯一語&#xff0c;今茲關左之行願以身驗之&#xff0c;若乃死生大事姑置焉。 巳未五月 二十一會猛士

八皇后问题和八数码问题的最陡上升爬山法、首选爬山法、随机重启爬山法、模拟退火算法的分析和实现

对经典算法的问题的回顾与感想 对八皇后问题和八数码问题分别用最陡上升爬山法、首选爬山法、随机重启爬山法、模拟退火算法来实现&#xff0c;并且分析他们的性能。 分析 要求实现的各个算法是有共同点的&#xff0c;比如&#xff0c;八皇后问题相关算法拥有相同的状态空间&…

Domino的压缩数据库的Load Compact命令

以下各表描述了完成 Compact 服务器任务时可以使用的选项。第一列列出了在 Domino Administrator 中使用“任务”“开始”工具或“文件”附签运行 Compact 时显示的选项。第二列列出了等价的命令行选项&#xff0c;可以在使用控制台命令或使用“程序”文档运行 Compact 时使用。…

go数据结构整理

初始化基本一样&#xff0c;不同点需要注意&#xff0c;make使用&#xff0c;nil变量的访问 array 初始化&#xff1a; 57 //修改元素值函数&#xff0c;指针版本和副本版本&#xff0c;指针版会修改原值58 func modify(arr [3]int, i int, v int) {59 //func modify(arr …

配置BGP

配置BGP<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" />一、 实验目的:配置BGP协议,实现两个isp之间的通信二、 实验拓扑结构图三、实验步骤1. 基本接口配置(略) 2. 配置bgp协议isp<?xml:namespace prefix …

临时表和内存表的区别

看到很多朋友对这些概念有些混淆&#xff0c;我来发表下我自己的观点。内存表&#xff1a;1. 参数控制&#xff1a;max_heap_table_size2. 到达上线后报错。3. 表定义保存在磁盘上&#xff0c;数据和索引保存在内存里面。4. 不能包含TEXT,BLOB等字段。临时表&#xff1a;1. 参数…

哈工大C语言公开课练兵编程(二)

版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 https://blog.csdn.net/juejing2271/article/details/79854773 </div><div id"content_views" class"markdown_views"><!-- flowchart 箭头图标 勿删 --…

MyXls初级教程

这些天使用MyXls导出Excel报表&#xff08;因为Apose.Cells要收费&#xff09;。感觉MyXls虽然功能远没有Cells强大&#xff0c;但是胜在开源、免费而且性能稳定可靠。用作出一般情况下的报表。足矣&#xff01; 记下几个初级使用方法&#xff0c;希望能够给初入门的人一点帮助…

竞赛ACM,究竟能为你的职场加分多少?

注&#xff1a;ACM 竞赛全称为 ACM 国际大学生程序设计竞赛&#xff0c;英文全称&#xff1a;ACM International Collegiate Programming Contest&#xff0c;简称 ACM-ICPC 或 ICPC &#xff09;。因为大家习惯简称为 ACM&#xff0c;文章中出现的 ACM 若无额外备注&#xff0…