KMP 算法(2):其细微之处

  • 2017 年 05 月 13 日
  • 技术

系列文章目录

KMP 算法(1):如何理解 KMP
KMP 算法(2):其细微之处

本篇来谈一谈 KMP 的一些细微之处,直接进入主题。

一:起始下标之 “争”:0 和 1展开目录

/* P 为模式串,下标从 0 开始 */
void GetNext(string P, int next[])
{
int p_len = P.size();
int i = 0; // P 的下标
int j = -1; // 相同真前后缀的长度
next[0] = -1; while (i < p_len)
{
if (j == -1 || P[i] == P[j])
{
i++;
j++;
next[i] = j;
}
else
j = next[j];
}
} /* 在 S 中找到 P 第一次出现的位置 */
int KMP(string S, string P, int next[])
{
GetNext(P, next); int i = 0; // S 的下标
int j = 0; // P 的下标
int s_len = S.size();
int p_len = P.size(); while (i < s_len && j < p_len)
{
if (j == -1 || S[i] == P[j]) // P 的第一个字符不匹配或 S[i] == P[j]
{
i++;
j++;
}
else
j = next[j]; // 当前字符匹配失败,进行跳转
} if (j == p_len) // 匹配成功
return i - j; return -1;
}

上述代码的起始下标都是从 0 开始的,但每个人对数组起始位置的编码习惯不同,分为两类:0 和 1。对于上面的代码,起始位置如果改为 1 的话又是怎样呢?

 

但它们的区别并不止如此。我们知道,KMP 算法的 next[i] 表示最长的相同真前后缀,但这对起始位置为 1 的 next[i] 却不再适用。

i 0 1 2 3 4 5 6

7

模式串 A B C D A B D

'\0'

next[i] -1 0 0 0 0 1 2

0

i 1 2 3 4 5 6 7

8

模式串 A B C D A B D

'\0'

next[i] 0 1 1 1 1 2 3

1

上面两个表格表展示的是:相同模式串下不同起始位置的 next 值对比。

相比之下,起始位置为 1 的 next 值比起始位置为 0 的 next 值多了 1。多 1,不是巧合,而是必然。这很容易证明。

在 GetNext() 中,j 从 0 开始(起始位置为 1),在走了相等步后停下依次赋值给 next[i],因此相较于起始位置为 0 的 next 总是多 1。这又引起了我们的思考,多了 1 后在模式匹配中,next 还会正确的实现跳转么?当然会了,next 多 1,同时模式串的起始位置也多了 1,这就好比数学中,从 a=b 转化为 a+1=b+1,形式不同但完全等价。

二:next[i] 里最不起眼处的妙用展开目录

先来看一个问题,在主串 S 中找到模式串 P 所有可以完全匹配的位置。

很简单,典型的 KMP 模式匹配。

假设起始位置都是从 0 开始,对于上图,若已找到主串的第一个完全匹配位置即 0--4,那么请问接下来模式串如何移动?

不知道各位读者有没有注意过模式串最后末尾处的 next 值代表什么?(末尾即为字符串的结尾标志:'\0')

它代表整个模式串的最长相同真前后缀。

利用这个 next 值,我们直接可以实现跳转,更快地找到下一个匹配点。

KMP(2)的更多相关文章

  1. KMP算法求解

    // KMP.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> using namespac ...

  2. 简单有效的kmp算法

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

  3. KMP算法

    KMP算法是字符串模式匹配当中最经典的算法,原来大二学数据结构的有讲,但是当时只是记住了原理,但不知道代码实现,今天终于是完成了KMP的代码实现.原理KMP的原理其实很简单,给定一个字符串和一个模式串 ...

  4. 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)

    前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...

  5. [KMP]【学习笔记】

    Oulipo Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 36916   Accepted: 14904 Descript ...

  6. KMP算法实现

    链接:http://blog.csdn.net/joylnwang/article/details/6778316 KMP算法是一种很经典的字符串匹配算法,链接中的讲解已经是很明确得了,自己按照其讲解 ...

  7. KMP专题

    1.[HDU 3336]Count the string(KMP+dp) 题意:求给定字符串含前缀的数量,如输入字符串abab,前缀是a.ab.aba.abab,在原字符串中出现的次数分别是2.2.1 ...

  8. KMP学习之旅

    说起kmp就要从字符串的匹配说起,下面我们谈谈字符串的匹配 给定一个原字符串:bababababababababb,再给定一个模式串:bababb,求模式串是否在源字符串中出现 最简单的方法就是遍历源 ...

  9. KMP模板

    参考:http://www.cnblogs.com/c-cloud/p/3224788.html #include<stdio.h> #include<string.h> vo ...

  10. 【字符串匹配】KMP算法和next数组的c/c++实现

    KMP算法基本思想有许多博客都写到了,写得也十分形象,不懂得可以参考下面的传送门,我就不解释基本思想了.本文主要给出KMP算法及next数组的计算方法(主要是很多网上的代码本人(相信应该是许多人吧)看 ...

随机推荐

  1. Oauth2.0(六):Resource Owner Password Credentials 授权和 Client Credentials 授权

    这两种简称 Password 方式和 Client 方式吧,都只适用于应用是受信任的场景.一个典型的例子是同一个企业内部的不同产品要使用本企业的 Oauth2.0 体系.在有些情况下,产品希望能够定制 ...

  2. 未能同步 iPhone XXX,因为这台电脑不再被授权使用在此iPhone上购买的项目。

    打包生成的ipa文件,安装到手机上,p12和ppf证书都正确,手机的udid也正确.用itunes安装到手机报错. 未能同步 iPhone XXX,因为这台电脑不再被授权使用在此iPhone上购买的项 ...

  3. win2008 server ping不同

    win2008 server ping不同,网络正常. 下图可以解决!!!

  4. Git revert merge

    从history1分出来的A, B两个branch A上有一些更改,例如 changeA2 changeA1 history1 B上有一些更改,例如 changeB2 changeB1 history ...

  5. ubuntu16.04安装tensorflow-gpu和cuda8.0加速训练

    转载请注明出处:http://www.cnblogs.com/buxizhizhoum/p/8086230.html 环境: 系统:ubuntu 16.04 cpu:i5 gpu:gt920m mem ...

  6. Windows7 64bit+python3.6环境下安装OpenCV3.3

    安装opencv3.3 打开windows的Python扩展包网址 根据自己的系统选择下载,这里我选择的是 通过pip3安装该whl文件,使用如下命令  pip3 install 该whl的绝对路径 ...

  7. Javascript系列:总体理解

    js是一个脚本客户端(浏览器)语言.和sql html类似.多练习. 没有排错的经验,弱类型语言,浏览器解释执行,出错也不会报错 预备 <!DOCTYPE html PUBLIC "- ...

  8. delphi修改QQ快捷方式的目标地址达到在启动QQ的同时也能运行自己想要启动的EXE可执行文件

    delphi修改QQ快捷方式的目标地址达到在启动QQ的同时也能运行自己想要启动的EXE可执行文件. 直接上代码,自已体会 !! Unit1.pas代码如下: unit Unit1; interface ...

  9. SpringMVC 文件上传 MultipartFile

    本的SpringMVC的搭建在我的上一篇文章里已经写过了,这篇文章主要说明一下如何使用SpringMVC进行表单上的文件上传以及多个文件同时上传的步骤 SpringMVC 基础教程 框架分析:http ...

  10. SO\PR回写的数据如下

    insert into OUT_ORDER_RES ---JAVA FOR PR ) as LGORT ,'SAPRFC' as ERNAM,out_pr.due_datetime,out_pr.so ...