给小白看的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//呵呵!看毛片算法
以前刚学的时候迷迷糊糊的,一看就懵圈,前几天捡起来的时候 发现还不会 于是研究了两天,自尊心严重受挫,今天的时候 突然一道灵光迸发,居然 感觉好像懂了,于是又琢磨起来 终于 我懂了 呵呵! ...
随机推荐
- Winserver+Apache+django部署
废话不多说,干活直接上. winserver2012 + django2.0.1 + apache 部署过程 python ==> 3.4 64位 https://www.python.org/ ...
- Golang学习--平滑重启
在上一篇博客介绍TOML配置的时候,讲到了通过信号通知重载配置.我们在这一篇中介绍下如何的平滑重启server. 与重载配置相同的是我们也需要通过信号来通知server重启,但关键在于平滑重启,如果只 ...
- linux系统命令学习系列-用户切换命令su,sudo
先复习一下上节内容: 用户组添加groupadd 用户组修改groupmod 用户组删除groupdel 作业创建一个id为501的组group1,然后改成group2, 同时id变为502,最后删除 ...
- linux的脚本应用for循环答应变量
#!/bin/bash for var in A B C ; do echo "var is $var" done
- 关于团购VPS的事情报告
作者 玄魂 2017-08-11 玄魂工作室-玄魂 玄魂工作室首先要抱歉,之前的说的继续组织大家购买vps的事情,不会再组织了.原因有以下几个:1)因为人多,需求各不相同,不好协调.2)服务都是购 ...
- 【iOS】 含tableView的ViewController基类的实现
上篇博客写了ViewController的基类的实现,这篇博客主要写在BaseViewController的基础上实现一个含tableView控件的基类的实现,主要给包含tableView的页面来继承 ...
- tomcat增加处理线程数量
修改server.xml <Executor name="tomcatThreadPool" namePrefix="catalina-exec-" ma ...
- Hibernate(十五):QBC检索、本地SQL检索和HQL删除
QBC检索 QBC查询就是通过使用Hibernate提供的Query By Criteria API来查询对象,这种API封装了SQL语句的动态拼装,对查询提供了更加面向对象的功能接口. 1)通过Cr ...
- Hibernate(三): org.hibernate.HibernateException: No CurrentSessionContext configured!
Hibernate版本5.2.9 获取Session的方式是sessionFactory.getCurrentSession(); 比较老一些的版本使用的是sessionFactory.openSes ...
- jquery、js调用iframe父窗口与子窗口元素的方法整理
1. jquery 在iframe子页面获取父页面元素代码如下: $("#objid", parent.document) 2. jquery在父页面 获取iframe子页面的元素 ...