如何加速朴素查找算法? KMP,当然还有其他算法,后续介绍.
  
 

Knuth–Morris–Pratt string search algorithm

Start at LHS of string, string[0], trying to match pattern, working right. 
Trying to match string[i] == pattern[j].

 
Given a search pattern, pre-build a table, next[j], showing, when there is a mismatch at pattern position j, where to reset j to
If match fails, keep i same, reset j to position next[j].
 

How to build the table

Everything else below is just how to build the table.

 

Construct a table showing where to reset j to

  1. If mismatch string[i] != pattern[0], just move string to i+1, j = 0
  2. If mismatch string[i] != pattern[1], we leave i the same, j = 0

    pattern = 1
    string = ... 1100000

  3. If mismatch string[i] != pattern[2], we leave i the same, and change j, but we need to consider repeats in pattern[0] .. pattern[1]

    pattern = 11
    string = ... 11100000 
    i stays same, j goes from 2 back to 1

    pattern = 10
    string = ... 10100000 
    i stays same, j goes from 2 back to 0

  4. If mismatch string[i] != pattern[j], we leave i the same, and change j, but we need to consider repeats in pattern[0] .. pattern[j-1]

Given a certain pattern, construct a table showing where to reset j to.

 

Construct a table of next[j]

For each j, figure out: 
next[j] = length of longest prefix in "pattern[0] .. pattern[j-1]" that matches the suffix of "pattern[1] .. pattern[j] 

next[j] = “最大匹配的子串的长度"  
That is:
  1. prefix must include pattern[0]
  2. suffix must include pattern[j]
  3. prefix and suffix are different
key
                                                        
Example for pattern  “ABABAC":
 

next[j] = length of longest prefix in "pattern[0] .. pattern[j-1]" that matches the suffix of "pattern[1] .. pattern[j]

当j+1位与s[k]位比较,不匹配时

j'=next[j], j’和s[k]比较了,j’移到了原j+1的位置

j 0 1 2 3 4 5
substring 0 to j A AB ABA ABAB ABABA ABABAC
longest prefix-suffix match none none A AB ABA none
next[j] 0 0 1 2 3 0
notes no prefix and suffix that are different 
i.e. next[0]=0 for all patterns
         

Given j, let n = next[j] 
"pattern[0] .. pattern[n-1]" = "pattern[j-(n-1)] .. pattern[j]"

"pattern[0] .. pattern[next[j]-1]" = "pattern[j-(next[j]-1)] .. pattern[j]"

e.g. j = 4, n = 3,

"pattern[0] .. pattern[2]" = "pattern[2] .. pattern[4]"

If match fails at position j+1(compare with s[j+1]), keep i same, reset pattern to position n(next[j]). 
Have already matched pattern[0] .. pattern[n-1],    pattern[0] .. pattern[n-1]=pattern[1] .. pattern[n]

e.g. We have matched ABABA so far. 
If next one fails, say we have matched ABA so far and then see if next one matches. 
That is, keep i same, just reset j to 3 (= precisely length of longest prefix-suffix match) 
Then, if match after ABA fails too, by the same rule we say we have matched A so far, reset to j = 1, and try again from there. 
In other words, it starts by trying to match the longest prefix-suffix, but if that fails it works down to the shorter ones until exhausted (no prefix-suffix matches left).

 

Algorithm to construct table of next[j]

Do this once, when the pattern comes in.
pattern[0] ... pattern[m-1] 
Here, i and j both index pattern.
就是说是两个模式串在比较
 

next[0] = 0
i = 1
j = 0
m = pattern.length while ( i < m )
{
  // on 1 step i=1,j=0
if ( pattern[j] == pattern[i] )
{
next[i] = j+1 // it’s i not j
i++
j++
}
else ( pattern[j] != pattern[i] )
{
if ( j > 0 ){
            // 比如[0],[1],[2]  === [4],[5][6]
            //  这时 [3] <> [7]
     //maybe there is another pattern we can shift right though,就是前缀和后缀
 j = next[j-1] // 因为next[j]就是给j+1用的,这个可记为定律,并且用j-1的原因还有0到[j-1]才有前后缀匹配的概念,
 // j是没有和模式串中的前缀匹配的,画画图就知道了
     }
else ( j == 0 )
{
 // 模式串的下标为0时,与文本串s的下标i的值不匹配,i右移一位,模式串右移一位,0右移还是0
       next[i] = 0
i++
j = 0 // redundant, just to make it clear what we are looping with
}
}
}
 
 
 

 

彻底弄明白之数据结构中的KMP算法的更多相关文章

  1. 彻底弄明白之数据结构中的排序七大算法-java实现

    package ds; /* * author : codinglion * contact: chenyakun@foxmail.com */ import java.util.Random; pu ...

  2. C++数据结构中的基本算法排序

    冒泡排序 基本思想:两两比较待排序的数,发现反序时交换,直到没有反序为止. public static void BubbleSort(int[] R) { for (int i = 0; i < ...

  3. 数据结构中常用的排序算法 && 时间复杂度 && 空间复杂度

    第一部分:数据结构中常用的排序算法 数据结构中的排序算法一般包括冒泡排序.选择排序.插入排序.归并排序和 快速排序, 当然还有很多其他的排序方式,这里主要介绍这五种排序方式. 排序是数据结构中的主要内 ...

  4. [POJ] 3461 Oulipo [KMP算法]

    Oulipo Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 23667   Accepted: 9492 Descripti ...

  5. 数据结构中很常见的各种树(BST二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树)

    数据结构中常见的树(BST二叉搜索树.AVL平衡二叉树.RBT红黑树.B-树.B+树.B*树) 二叉排序树.平衡树.红黑树 红黑树----第四篇:一步一图一代码,一定要让你真正彻底明白红黑树 --- ...

  6. Java高级工程师需要弄明白的20个知识点

    一般的程序员或许只需知道一些JAVA的语法结构,能对数据库数据进行CRUD就可以应付了.但要成为JAVA(高级) 工程师,就要对JAVA做比较深入的研究,需要不断学习进步,以下对高级工程师需要突破的知 ...

  7. 弄明白CMS和G1,就靠这一篇了

    目录 1 CMS收集器 安全点(Safepoint) 安全区域 2 G1收集器 卡表(Card Table) 3 总结 4 参考 在开始介绍CMS和G1前,我们可以剧透几点: 根据不同分代的特点,收集 ...

  8. [Data Structure] 数据结构中各种树

    数据结构中有很多树的结构,其中包括二叉树.二叉搜索树.2-3树.红黑树等等.本文中对数据结构中常见的几种树的概念和用途进行了汇总,不求严格精准,但求简单易懂. 1. 二叉树 二叉树是数据结构中一种重要 ...

  9. 几张图弄明白ios布局中的尺寸问题

    背景 先说说逆向那事.各种曲折..各种技术过时,老老实实在啃看雪的帖子..更新会有的. 回正题,这里讨论的是在Masnory框架下的布局问题.像我这种游击队没师傅带,什么都得自己琢磨,一直没闹明白下面 ...

随机推荐

  1. Delphi字符串与字符数组之间的转换(初始化的重要性)

    紧接着上篇博客讲解的内容: 将Char型数组转换为string类型还有下面的这种方法 但是我在测试的时候遇到了一些问题,并在下面进行了解释和总结 先说出我的总结 其实我们在学习编程的时候(比如我之前学 ...

  2. 【stut 逆置正整数】

    C语言实验——逆置正整数 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 输入一个三位正整数,将它反向输出. 输入 3位正整数. ...

  3. windows常用命令

    打开"运行"对话框(Win+R),输入cmd,打开控制台命令窗口... 也可以通过cmd /c 命令 和 cmd /k 命令的方式来直接运行命令 注:/c表示执行完命令后关闭cmd ...

  4. 攻城狮在路上(壹) Hibernate(十五)--- Hibernate的高级配置

    一.配置数据库连接池: 1.使用默认的数据库连接池: Hibernate提供了默认了数据库连接池,它的实现类为DriverManegerConnectionProvider,如果在Hibernate的 ...

  5. <转>删除文件夹下所有的.svn文件

    当使用了svn版本控制系统后每个目录下都会有一个.svn目录存在,开发完当交付产品或者上传到服务器时一般要把这些目录删除,这里总结了一下在linux和win下的办法. 一.在linux下 删除这些目录 ...

  6. DateTime还是DateTimeOffset?Now还是UtcNow?

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:新年第一篇文章,就来谈谈关于时间的简单技术问题:该用DateTime还是DateTim ...

  7. 原生JavaScript 全特效微博发布面板效果实现

    javaScript实现微博发布面板效果.---转载白超华 采用的js知识有: 正则表达式区分中英文字节.随机数生成等函数 淡入淡出.缓冲运动.闪动等动画函数 onfocus.onblur.oninp ...

  8. 【java基础】面向过程~面向对象

    相信大家都知道这两个东西,可是大家是如何知道的呢?我们又该如何区分这个东西到底是面向过程还是面向对象的呢? 那,我们首先就要知道什么是面向过程,什么是面向对象: 面向过程"(Procedur ...

  9. 分享一个漂亮WPF界面框架创作过程及其源码(转)

    本文会作为一个系列,分为以下部分来介绍: (1)见识一下这个界面框架: (2)界面框架如何进行开发: (3)辅助开发支持:Demo.模板.VsPackage制作. 框架源码如下所示. 本文介绍第(1) ...

  10. JS获得鼠标位置

    <body> <script> function mouseMove(ev) { ev = ev || window.event; var mousePos = mouseCo ...