浅谈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算法的更多相关文章

  1. 简单有效的kmp算法

    以前看过kmp算法,当时接触后总感觉好深奥啊,抱着数据结构的数啃了一中午,最终才大致看懂,后来提起kmp也只剩下“奥,它是做模式匹配的”这点干货.最近有空,翻出来算法导论看看,原来就是这么简单(先不说 ...

  2. KMP算法学习

    kmp算法完成的任务是:给定两个字符串O和f,长度分别为n和m,判断f是否在O中出现,如果出现则返回出现的位置.常规方法是遍历a的每一个位置,然后从该位置开始和b进行匹配,但是这种方法的复杂度是O(n ...

  3. 字符串匹配的KMP算法详解及C#实现

    字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD" ...

  4. 经典算法题每日演练——第七题 KMP算法

    原文:经典算法题每日演练--第七题 KMP算法 在大学的时候,应该在数据结构里面都看过kmp算法吧,不知道有多少老师对该算法是一笔带过的,至少我们以前是的, 确实kmp算法还是有点饶人的,如果说红黑树 ...

  5. <转>KMP算法详解

    看了好久的KMP算法,都一直没有看明白,直到看到了这篇博客http://www.tuicool.com/articles/e2Qbyyf让我瞬间顿悟. 如果你看不懂 KMP 算法,那就看一看这篇文章 ...

  6. 数据结构20:KMP算法(快速模式匹配算法)详解

    通过上一节的介绍,学习了串的普通模式匹配算法,大体思路是:模式串从主串的第一个字符开始匹配,每匹配失败,主串中记录匹配进度的指针 i 都要进行 i-j+1 的回退操作(这个过程称为“指针回溯”),同时 ...

  7. 数据结构4.3_字符串模式匹配——KMP算法详解

    next数组表示字符串前后缀匹配的最大长度.是KMP算法的精髓所在.可以起到决定模式字符串右移多少长度以达到跳跃式匹配的高效模式. 以下是对next数组的解释: 如何求next数组: 相关链接:按顺序 ...

  8. 快速字符串匹配一: 看毛片算法(KMP)

    前言 由于需要做一个快速匹配敏感关键词的服务,为了提供一个高效,准确,低能耗的关键词匹配服务,我进行了漫长的探索.这里把过程记录成系列博客,供大家参考. 在一开始,接收到快速敏感词匹配时,我就想到了 ...

  9. kmp//呵呵!看毛片算法

    以前刚学的时候迷迷糊糊的,一看就懵圈,前几天捡起来的时候 发现还不会 于是研究了两天,自尊心严重受挫,今天的时候  突然一道灵光迸发,居然 感觉好像懂了,于是又琢磨起来  终于  我懂了  呵呵!   ...

随机推荐

  1. js定时刷新页面.

    //页面定时刷新.2017.09.27 $(document).ready(function () { self.setInterval(function () { var d = new Date( ...

  2. php的api及登录的权限验证

    类,库,接口(APi),函数,这些概念都是根据问题规模的大小来界定的.一个很小的问题肯定没有必要写成一个库,只需要写几句话就行了. 但是比如一个登录验证,这个功能很强大,很通用,可能前台后台都需要用到 ...

  3. LR之error(一)

    1 录制时频繁卡死的解决方案 添加数据保护 路径:计算机--高级系统设置(环境变量设置的上级窗口)--高级--设置--数据执行保护 更改LR录制设置,将run-time setting的brower改 ...

  4. vue组件详解(四)——使用slot分发内容

    一.什么是slot 在使用组件时,我们常常要像这样组合它们: <app> <app-header></app-header> <app-footer>& ...

  5. 说说Java代理模式

    代理实现可以分为静态代理和动态代理. 静态代理 静态代理模式其实很常见,比如买火车票这件小事:黄牛相当于是火车站的代理,我们可以通过黄牛买票,但只能去火车站进行改签和退票.在代码实现中相当于为一个委托 ...

  6. webgoat——XSS

    Stage 1: Stored XSS(存储XSS攻击 黑别人) 实验内容:主要是用户"Tom"(攻击者)在自己的个人资料中添加了恶意代码(比如最简单的<script> ...

  7. Angular 学习笔记 (路由外传 - RouteReuseStrategy)

    refer : https://github.com/angular/angular/issues/10929 https://stackoverflow.com/questions/41280471 ...

  8. matlab 对tif数据高程图的处理分析

    temp=z(101:2200,101:2200) 根据图像属性可得此为2300*2300的tif图像,由于需要将其划分为9宫格,所以begin点设置为101,end点设置为2200,temp转化为可 ...

  9. Java Class文件格式详解

    magic[4字节] 魔数,用来判断是否可以被虚拟机使用.固定值为0xCAFEBABE(咖啡宝贝)minor_version[2字节] 次版本号major_version[2字节] 主版本号,低版本的 ...

  10. 基于Verilog HDL的超前进位全加器设计

    通常我们所使用的加法器一般是串行进位,将从输入的ci逐位进位地传递到最高位的进位输出co,由于电路是有延迟的,这样的长途旅行是需要时间的,所以为了加快加法器的运算,引入了超前进位全加器. 全加器的两个 ...