`
那次流鼻血
  • 浏览: 33013 次
  • 性别: Icon_minigender_1
  • 来自: 青岛
社区版块
存档分类
最新评论

KMP算法解析

 
阅读更多

本文转载出处:http://kb.cnblogs.com/page/176818/

 

字符串匹配是计算机的基本任务之一。

  举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD"?

  许多算法可以完成这个任务,Knuth-Morris-Pratt算法(简称KMP)是最常用的之一。它以三个发明者命名,起头的那个K就是著名科学家Donald Knuth。

  这种算法不太容易理解,网上有很多解释,但读起来都很费劲。直到读到Jake Boxer的文章,我才真正理解这种算法。下面,我用自己的语言,试图写一篇比较好懂的KMP算法解释。

  1.

  首先,字符串"BBC ABCDAB ABCDABCDABDE"的第一个字符与搜索词"ABCDABD"的第一个字符,进行比较。因为B与A不匹配,所以搜索词后移一位。

  2.

  因为B与A不匹配,搜索词再往后移。

  3.

  就这样,直到字符串有一个字符,与搜索词的第一个字符相同为止。

  4.

  接着比较字符串和搜索词的下一个字符,还是相同。

  5.

  直到字符串有一个字符,与搜索词对应的字符不相同为止。

  6.

  这时,最自然的反应是,将搜索词整个后移一位,再从头逐个比较。这样做虽然可行,但是效率很差,因为你要把"搜索位置"移到已经比较过的位置,重比一遍。

  7.

  一个基本事实是,当空格与D不匹配时,你其实知道前面六个字符是"ABCDAB"。KMP算法的想法是,设法利用这个已知信息,不要把"搜索位置"移回已经比较过的位置,继续把它向后移,这样就提高了效率。

  8.

  怎么做到这一点呢?可以针对搜索词,算出一张《部分匹配表》(Partial Match Table)。这张表是如何产生的,后面再介绍,这里只要会用就可以了。

  9.

  已知空格与D不匹配时,前面六个字符"ABCDAB"是匹配的。查表可知,最后一个匹配字符B对应的"部分匹配值"为2,因此按照下面的公式算出向后移动的位数:

  移动位数 = 已匹配的字符数 - 对应的部分匹配值

  因为 6 - 2 等于4,所以将搜索词向后移动4位。

  10.

  因为空格与C不匹配,搜索词还要继续往后移。这时,已匹配的字符数为2("AB"),对应的"部分匹配值"为0。所以,移动位数 = 2 - 0,结果为 2,于是将搜索词向后移2位。

  11.

  因为空格与A不匹配,继续后移一位。

  12.

  逐位比较,直到发现C与D不匹配。于是,移动位数 = 6 - 2,继续将搜索词向后移动4位。

  13.

  逐位比较,直到搜索词的最后一位,发现完全匹配,于是搜索完成。如果还要继续搜索(即找出全部匹配),移动位数 = 7 - 0,再将搜索词向后移动7位,这里就不再重复了。

  14.

  下面介绍《部分匹配表》是如何产生的。

  首先,要了解两个概念:"前缀"和"后缀"。 "前缀"指除了最后一个字符以外,一个字符串的全部头部组合;"后缀"指除了第一个字符以外,一个字符串的全部尾部组合。

  15.

  "部分匹配值"就是"前缀"和"后缀"的最长的共有元素的长度。以"ABCDABD"为例,

  - "A"的前缀和后缀都为空集,共有元素的长度为0;

  - "AB"的前缀为[A],后缀为[B],共有元素的长度为0;

  - "ABC"的前缀为[A, AB],后缀为[BC, C],共有元素的长度0;

  - "ABCD"的前缀为[A, AB, ABC],后缀为[BCD, CD, D],共有元素的长度为0;

  - "ABCDA"的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A],共有元素为"A",长度为1;

  - "ABCDAB"的前缀为[A, AB, ABC, ABCD, ABCDA],后缀为[BCDAB, CDAB, DAB, AB, B],共有元素为"AB",长度为2;

  - "ABCDABD"的前缀为[A, AB, ABC, ABCD, ABCDA, ABCDAB],后缀为[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的长度为0。

  16.

  "部分匹配"的实质是,有时候,字符串头部和尾部会有重复。比如,"ABCDAB"之中有两个"AB",那么它的"部分匹配值"就是2("AB"的长度)。搜索词移动的时候,第一个"AB"向后移动4位(字符串长度-部分匹配值),就可以来到第二个"AB"的位置。

分享到:
评论

相关推荐

    数据结构教学中KMP算法解析.pdf

    此外,KMP算法具有一定的局限性,例如在某些特殊模式串的匹配问题中,可能需要结合其他算法或者对KMP算法本身进行修改才能得到更好的效率。 总的来说,KMP算法是数据结构中字符串匹配领域的一个重要算法,其高效的...

    字符串KMP算法c语言

    ### 字符串KMP算法C语言实现解析 在计算机科学领域,字符串匹配是常见的操作之一,其中KMP算法(Knuth-Morris-Pratt算法)因其高效性而被广泛使用。KMP算法由Donald Knuth、James H.Morris以及Vaughan Pratt共同...

    完全掌握KMP算法思想

    ### 完全掌握KMP算法思想 #### KMP算法概览 KMP算法,全称为Knuth-Morris-Pratt算法,是一种高效的字符串匹配算法,主要用于在一个文本串中寻找一个模式串的所有出现位置。相较于朴素的字符串匹配算法,KMP算法...

    KMP.rar_KMP_KMP算法_串 KMP算法_字符串匹配

    本文将深入解析KMP算法的原理、实现过程及其在实际应用中的价值。 KMP算法由Donald Knuth、Vaughan Pratt和James H. Morris三位学者于1970年提出,它是一种高效的字符串匹配算法,能在O(n)的时间复杂度内完成字符串...

    kmp算法 编程

    本文将从KMP算法的基本原理、实现细节以及示例代码出发,全面解析KMP算法的精髓。 #### KMP算法的基本原理 KMP算法的核心思想是利用模式串的部分匹配信息来避免重复匹配,从而提高搜索效率。具体而言,KMP算法通过...

    字符串匹配的KMP算法.rar_KMP_KMP算法_kmp 字符串匹配_字符串匹配_文件

    5. www.pudn.com.txt文件可能包含的是KMP算法的实际代码示例或者进一步的解释,文档字符串匹配的KMP算法.doc则可能是详细讲解KMP算法的理论、步骤以及实例解析,供学习者参考。 总的来说,KMP算法是一种高效的字符...

    KMP算法 java版

    接下来,我们将根据提供的Java代码片段来详细解析KMP算法的具体实现。 ```java package com.test.kmp; public class StringMatch { private String S; private String T; // getter 和 setter 方法省略... ...

    kmp算法-基于cuda实现kmp算法.zip

    以下是对KMP算法和CUDA实现的详细解析: 1. **KMP算法原理**: KMP算法的核心是构造一个部分匹配表,这个表记录了模式串中每个字符之前最长的公共前后缀长度。当模式串在文本串中比较时,如果遇到不匹配的情况,...

    kmp算法步骤解析.md

    kmp算法

    使用c编写KMP算法,可以完美运行

    ### 使用C语言实现KMP算法 #### 知识点概览 本文将详细介绍如何使用C语言来实现KMP(Knuth-Morris-Pratt)算法,并通过提供的代码示例进行解释。KMP算法是一种高效的字符串匹配算法,它可以避免在模式匹配过程中...

    kmp算法-基于Java实现kmp字符串搜索算法.zip

    本文将详细介绍KMP算法的原理,并以Java语言为例,解析其实现过程。 1. KMP算法概述: KMP算法的核心思想是避免对已匹配的字符进行不必要的比较,通过预处理模式串来创建一个“部分匹配表”,用于指导在主串中遇到...

    kmp基本算法演示.rar

    《深入理解KMP算法:基于易语言的实现与解析》 KMP(Knuth-Morris-Pratt)算法,一种在字符串中查找子串的高效算法,由唐纳德·克努斯、詹姆斯·莫里斯和弗雷德里克·普拉特三位学者于1970年提出。其主要解决了在主...

    数据结构BF和KMP算法

    ### 数据结构中的BF和KMP算法 #### BF(Brute Force)算法 BF算法是一种简单的字符串匹配算法,也称为暴力匹配算法。其基本思想是将模式串T在主串S中从头开始逐个字符比较,若匹配成功则返回位置,否则继续下一轮...

    KMP算法介绍.pdf

    #### 五、KMP算法实例解析 以题目中给出的例子为例,假设主串A="abababaababacb",模式串B="ababacb",下面展示具体的匹配过程: 1. **初始化阶段**: - 主串A的索引i=0,模式串B的索引j=0; - 初始化`next`数组...

    文学研究助手(字符串的查找\模式匹配\KMP算法)

    《文学研究助手——深入解析KMP算法在字符串查找与模式匹配中的应用》 在文学研究领域,高效地处理文本信息是至关重要的。本项目“文学研究助手”正是为解决这一问题而设计,它利用C语言实现,核心算法是著名的KMP...

    数据结构-KMP算法原理

    ### 数据结构-KMP算法原理 #### 一、引言 KMP算法(Knuth-Morris-Pratt算法)是一种在文本中查找模式串的高效算法,由Donald Knuth、James H. Morris和Vaughan Pratt三人共同提出。与传统的暴力匹配(如Boyer-...

    KMP改进算法

    改进后的KMP算法在诸如文本搜索、文件路径匹配、正则表达式解析等领域有着广泛的应用。例如,当在大量文件名中寻找符合特定模式(如`*.txt`)的文件时,改进的KMP算法能有效提升查找效率。 总结,KMP改进算法通过...

    关于数据结构中的kmp算法详解

    本文将深入解析KMP算法的原理,并通过实例演示其执行过程,旨在为初学者提供一个清晰的学习路径。 #### KMP算法的核心思想 KMP算法的核心在于利用模式串自身的部分匹配信息来避免不必要的比较。在传统的模式匹配...

    kmp算法要点和难点具体应用场景.zip

    《KMP算法要点和难点:具体应用场景》 KMP(Knuth-Morris-Pratt)算法是一种在字符串中查找子串出现位置的高效算法,由Donald Knuth、James H. Morris和 Vaughan Pratt三位学者于1970年提出。这个算法避免了在主串...

    易语言源码KMP算法模块源码.rar

    《易语言KMP算法模块源码解析》 易语言,作为中国本土开发的一款特色编程语言,以其独特的中文编程界面和简单易学的特点,受到了许多初学者的欢迎。本篇文章将聚焦于易语言中的一个核心算法模块——KMP(Knuth-...

Global site tag (gtag.js) - Google Analytics