给小白看的KMP算法
浅谈KMP算法:
(大部分人的KMP写法都是不一样的)
一:
先给大家推荐一个讲kmp比较好理解的一个博客:阮一峰
二:
下面介绍一点相关概念:
栗子:
P串: ABCBD
前缀:A,AB,ABC,ABCB,ABCBD
真前缀:A,AB,ABC,ABCB
后缀:D,BD,CBD,BCBD,ABCBD
真后缀:D,BD,CBD,BCBD
KMP算法里的next数组的含义:
栗子:
P串: ABCDABD
next[] = {-1, 0, 0, 0, 0, 1, 2, 0, };
next[i] 的含义:P串前 i 个字符(包括第 i 个)的最长真前缀后缀公共长度;
如 i = 5时:
真前缀:A,AB,ABC,ABCD
真后缀:BCDA,CDA,DA,A
显而易见, 前缀和后缀相同的只有 A,而 A 的长度为 1,所以next[5] = 1;
next数组求法:
//用通俗的语句说就是k是用来表示子串中前k个和后k个是相同的,i是用来遍历数组
void get_next(char *t,int lent){
nex[] = -;
for(int i = ,k = -;i < lent;){
if(k==-||t[i] == t[k]){
++k;++i;
nex[i]=k;
}else k = nex[k];
/*如果c[i]和c[k]中字符不同说明匹配是失败,要把k的值重新退到next[ k ]
直到两者相同才停止。这样做的好处是没必要再重新从头再来,节约时间*/
}
}
简单KMP算法的实现:
//返回主串中匹配的位置(第一个),如果不匹配返回-1;
int kmp(char *s,char *t,int lens,int lent)
{
int i = , j = ;
while(i < lens&&j<lent) {
if(j==-||s[i] == t[j]){
i++;j++;
if(j==lent){
return i-j+;
}
}else j=nex[j];
}
return -;
}
几道例题:
洛谷P3375:
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 1e6 + ;
int nex[maxn];
char s[maxn],t[maxn];
int lens,lent;
void get_next(){
nex[] = -;
for(int i = ,k = -;i < lent;){
if(k==-||t[i] == t[k]){
++k;++i;
nex[i]=k;
}else k = nex[k];
}
} void kmp()
{
int i = , j = ;
while(i < lens&&j<lent) {
if(j==-||s[i] == t[j]){
i++;j++;
if(j==lent){
printf("%d\n",i-j+);
j=nex[j];
}
}else j=nex[j];
}
}
int main(){
while(~scanf("%s %s",s,t)){
lens=strlen(s);
lent=strlen(t);
get_next();
kmp();
for(int i=;i<=lent;++i){
printf("%d%c",nex[i],i==lent?'\n':' ');
}
}
return ;
}
给小白看的KMP算法的更多相关文章
- 简单有效的kmp算法
以前看过kmp算法,当时接触后总感觉好深奥啊,抱着数据结构的数啃了一中午,最终才大致看懂,后来提起kmp也只剩下“奥,它是做模式匹配的”这点干货.最近有空,翻出来算法导论看看,原来就是这么简单(先不说 ...
- KMP算法学习
kmp算法完成的任务是:给定两个字符串O和f,长度分别为n和m,判断f是否在O中出现,如果出现则返回出现的位置.常规方法是遍历a的每一个位置,然后从该位置开始和b进行匹配,但是这种方法的复杂度是O(n ...
- 字符串匹配的KMP算法详解及C#实现
字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD" ...
- 经典算法题每日演练——第七题 KMP算法
原文:经典算法题每日演练--第七题 KMP算法 在大学的时候,应该在数据结构里面都看过kmp算法吧,不知道有多少老师对该算法是一笔带过的,至少我们以前是的, 确实kmp算法还是有点饶人的,如果说红黑树 ...
- <转>KMP算法详解
看了好久的KMP算法,都一直没有看明白,直到看到了这篇博客http://www.tuicool.com/articles/e2Qbyyf让我瞬间顿悟. 如果你看不懂 KMP 算法,那就看一看这篇文章 ...
- 数据结构20:KMP算法(快速模式匹配算法)详解
通过上一节的介绍,学习了串的普通模式匹配算法,大体思路是:模式串从主串的第一个字符开始匹配,每匹配失败,主串中记录匹配进度的指针 i 都要进行 i-j+1 的回退操作(这个过程称为“指针回溯”),同时 ...
- 数据结构4.3_字符串模式匹配——KMP算法详解
next数组表示字符串前后缀匹配的最大长度.是KMP算法的精髓所在.可以起到决定模式字符串右移多少长度以达到跳跃式匹配的高效模式. 以下是对next数组的解释: 如何求next数组: 相关链接:按顺序 ...
- 快速字符串匹配一: 看毛片算法(KMP)
前言 由于需要做一个快速匹配敏感关键词的服务,为了提供一个高效,准确,低能耗的关键词匹配服务,我进行了漫长的探索.这里把过程记录成系列博客,供大家参考. 在一开始,接收到快速敏感词匹配时,我就想到了 ...
- kmp//呵呵!看毛片算法
以前刚学的时候迷迷糊糊的,一看就懵圈,前几天捡起来的时候 发现还不会 于是研究了两天,自尊心严重受挫,今天的时候 突然一道灵光迸发,居然 感觉好像懂了,于是又琢磨起来 终于 我懂了 呵呵! ...
随机推荐
- Project facet is Java version 1.7 is not spported
在移植eclipse项目时,如果遇到 "Project facet Java version 1.7 is not supported." 项目中的jdk1.7不支持.说明项目是其 ...
- border 三角形 有边框的 东西南北的 气泡三角形
链接地址:http://www.cnblogs.com/blosaa/p/3823695.html
- JAVA_SE基础——60.初识Object
java是面向对象的语言,核心思想:找适合 的对象做适合 的事情:方式一:自定义类,然后通过自定义的类创建对象.方式二:sun提供了很多的类给我使用,我们只需要认识这些类,我们就可以通过这些类创建对象 ...
- python实现维吉尼亚解密
# -*-coding:UTF-8-*- from sys import stdout miwen = "KCCPKBGUFDPHQTYAVINRRTMVGRKDNBVFDETDGILTXR ...
- 你考虑清楚了吗就决定用 Bootstrap ?
近年来,在前端项目中, Bootstrap 已经成为了一个非常受欢迎的工具. Bootstrap 的确有很多优点,然而,如果你的团队中恰好有一个专职的前端工程师.那我推荐你们不要使用 Bootstra ...
- python入门(10)使用List和tuple
python入门(10)使用List和tuple list Python内置的一种数据类型是列表:list.list是一种有序的集合,可以随时添加和删除其中的元素. 比如,列出班里所有同学的名字,就可 ...
- maven快速下载jar镜像
<!--国内镜像--><mirror> <id>CN</id> <name>OSChina Central</name> ...
- 两款不同应用场景的Wpf分页控件
简介 今天给大家分享两个Wpf分页控件,本篇博客主要介绍一些实现思路和使用方法,具体实现和应用代码请参考文末的Demo链接 废话不多说,先看一下效果~ (两款控件显示效果是一样的) 实现思路 一款控件 ...
- Struts(二十五):自定义验证器
编程验证 Struts2提供了一个Validateable接口,可以使用Action类实现这个接口以提供编程验证: ActionSupport类已经实现了Validateable接口. public ...
- 深度学习中Xavier初始化
"Xavier"初始化方法是一种很有效的神经网络初始化方法,方法来源于2010年的一篇论文<Understanding the difficulty of training ...