题目描述

暴力解法:枚举原串起始位置,逐个匹配,复杂度O(mn)。

优化思路:失配时,前面已匹配的字符可以提供信息。

KMP算法:

对于模式串任意位置 i ,如果我们知道一个 k 使得 i 位置前的 k 个元素和模式串最开始的前 k 个元素一一相等,那么第 i 个元素失配时就可以之间从第 k + 1 个元素开始继续匹配,这就利用到了失配前的匹配信息。

于是我们想构造这样一个数组 next_val[]  使得 next_val[i] 指向第 i 元素失配时下一个匹配的位置。

例如对于模式串abcabd,它的 next_val[] 数组如下,其中 –1 表示第一个元素也无法匹配:

下标 0 1 2 3 4 5
字符 a b c a b d
next_val -1 0 0 0 1 2

其实这个数组还可以优化,就是要把失配提供的信息也利用上。

如果第 i 个元素已经失配,那么如果 next_val[i] 对应的元素与第 i 个元素相同,那么其实不用进行下一次比较,于是把 next_val[i] = next_val[next_val[i]]。

下面的问题就是如何求解 next_val 数组。

这是个比较简单的递推问题,即“如果已知 next_val[1,…,k-1],如何求 next_val[k]”?

结合 next_val 数组的定义和以下代码不难理解,重点是理解第6行。

void init_next() {int len = strlen(ptn);next_val[0] = -1;int i = 0, j = next_val[i];while (i < len) {if (j == -1 || ptn[i] == ptn[j]) {next_val[i + 1] = j + 1;if (j != -1) {next_val[i] = next_val[next_val[i]];}i++;j++;}else {j = next_val[j];}}
}

得到了 next_val 数组后,就逐个匹配,失配时模式串位置标记通过 next_val 数组跳就行了。

代码如下:

int kmp() {init_next();int ans = 0;int str_len = strlen(str);int ptn_len = strlen(ptn);int i = 0, j = 0;while (i < str_len) {if (j == -1 || str[i] == ptn[j]) {i++;j++;}else {j = next_val[j];}if (j == ptn_len) {ans++;}}return ans;
}

吐槽:KMP算法思想虽然简单,理解起来也不复杂,但是要讲清楚太难了,不懂的话其实可以结合例子理解一下 next_val 的求法。

转载于:https://www.cnblogs.com/xblade/p/4445177.html

[hiho 03]KMP算法相关推荐

  1. hiho 1015 KMP算法 CF 625 B. War of the Corporations

    #1015 : KMP算法 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在 ...

  2. hiho一下 第三周---KMP算法

    KMP算法 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上 ...

  3. hiho一下 第三周 Hiocoder #1015 : KMP算法

    #1015 : KMP算法 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在 ...

  4. (hiho一下第三周)#1015 KMP算法 【模版】

    题目1 : KMP算法 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程 ...

  5. KMP算法之NEXT数组代码原理分析 - 数据结构和算法38

    KMP算法之NEXT数组代码原理分析 让编程改变世界 Change the world by program KMP算法之NEXT数组代码原理分析 NEXT数组:当模式匹配串T失配的时候,NEXT数组 ...

  6. KMP算法字符串模式匹配

    KMP字符串模式匹配详解 来自CSDN     A_B_C_ABC 网友 KMP字符串模式匹配通俗点说就是一种在一个字符串中定位另一个串的高效算法.简单匹配算法的时间复杂度为O(m*n);KMP匹配算 ...

  7. 解析网页(KMP算法实现部分)

    用kmp算法实现在一个网页内网址的提取,整个项目在这点击打开链接.只要把里边的kmpDlg.cpp文件了的部分内容用以下代码替换即可. kmp算法无回溯的查找匹配串所在位置,效率更高····· voi ...

  8. 【模式匹配】之 —— KMP算法详解及证明

    一    RevisionsHistory 1 一       Revisions History 二       前言 三       关于算法学习 四       KMP算法始末 KMP算法是用来 ...

  9. kmp算法及manacher算法分析

    1.KMP算法 kmp算法主要用来解决字符串匹配的问题,即一个字符串是否是另外一个字符串的子串. (1)暴力法 首先想到的方法就是暴力匹配法,即两个字符串按位进行匹配,如果遇到不相同的,则从从头开始的 ...

最新文章

  1. Java 对象的生命周期
  2. 使用数字万用表判断三极管管脚!
  3. vector机器人 PHOTOS TAKEN BY VECTOR 由 VECTOR 拍摄的照片
  4. Swift之父退出核心团队,自曝原因:环境有毒!
  5. 关于ThinkPHP的一些编程技巧
  6. 数据库---mysql内置功能
  7. 日期格式校验方法工具
  8. 卷积神经网络经典模型要点
  9. GPU Gems2 - 7 带位移映射的细分表面自适应镶嵌
  10. Java:不朽的对象和对象复活
  11. php 实现贪吃蛇游戏,C++实现简单贪吃蛇游戏
  12. 【转载】我是一个线程(修订版)
  13. Android 使用dagger2进行依赖注入(基础篇)
  14. 编程师代码G都喜欢的|细致场景森系插画手机壁纸
  15. windows VC++获取磁盘名称和序列号
  16. LoadRunner字符串编码转换函数:lr_convert_string_encoding
  17. 心电图分析软件_家用心电图机,一键出报告,让你在家就能看懂心电图!
  18. easyui及eova下select:option、find无法直接取值的解决办法
  19. FPGA学习小例子:38译码器设计与仿真
  20. 火焰检测的基本方法研究和实现

热门文章

  1. 转: 我的助理辞职了.
  2. 未明学院:咨询/投行/四大/券商/私募,上交学姐传授商科实习秘籍!
  3. 使用开源代码搭建资产管理系统
  4. 苏轼与江西交通的不解之缘
  5. python opencv cv2.imread
  6. 推荐轻量级易用的3D建模软件Wings3D和Sculptris
  7. Java :Annotation(注释)
  8. 关于Uibot Creator离线激活无法显示机器码的解决方案(流程/机器人/自动化)
  9. 第二届“强网”拟态防御国际精英挑战赛:背后的男人们!
  10. LZ77算法 Python实现