字符串模式匹配算法--详解KMP算法

在软考的复习中,看到过几次  字符串的模式匹配算法。看起来挺难的。所以花了点时间查了查关于字符串匹配的算法。下面详细介绍一下KMP模式匹配算法

什么是字符串的匹配?

在文章中进行查找。需要找到要查找的内容所在的位置。就是字符串的匹配。

朴素的模式匹配算法

朴素的模式匹配算法,就是把要查找的内容,一步步的与要查找的文章进行进行比较。如果匹配失败,则主串和字串回溯。字串位置加1.重新匹配。

模式匹配算法的流程如下:

在匹配失败的情况下,模式串仅右移一个
之后。在从头开始匹配。

两个for循环

For i=1 to length(主串)-length(模式串)+1

For j=1 to length(模式串)

所以时间复杂度为:O((n-m+1)*m)  在模式串较小的情况下,时间复杂度为O(mn)

KMP匹配算法:

在看这个例子的时候,如果匹配失败。令模式串右移一个位置。重新开始匹配。这种情况。主串与模式串的指针都要回溯。

在朴素的匹配算法中,无论已经匹配正确了多少个字符,在遇到不配的情况下,指针就要进行回溯。重新开始下一轮匹配。这样就会造成资源的浪费。

KMP算法,就是消除这种浪费。KMP算法要利用已经匹配好的部分字符串。

用一个例子来说明,是如何利用已经匹配的字符串的。

c匹配失败。但是前面已经有匹配成功的子串为“abaaba“  所以  要利用这个已经匹配好的字符串。

只有在这种情况下,右移才能最大化。才能使得指针不用回溯。

在已经匹配成功的子串中。是如何求出最大偏移量呢?

可以利用的子串:

在这就要使用,字符串的前缀 和后缀了。

比如字符串“ABCD”的

前缀:A、AB、ABC、ABCD

后缀:D、CD、BCD、ABCD

只要找到,前缀和后缀中 相同的部分。就是可以利用的部分。

例子中:

abaaba前缀:a、ab、aba、abaa、abaab

abaaba后缀:a、ba、aba、aaba、baaba

找到前缀和后缀中的公共部分长度最大的为"aba"  所以要利用的串为"aba"。

模式串的右移量:

利用已经匹配好的字符串,来确定子串
右移的位数。利用next函数。

根据以上的描述,指针一直向右,不回溯。所以要匹配的长度为m+n

所以KMP算法的时间复杂度为:O(m+n)

在KMP匹配算法中,常常看到。一个next函数:

形式如:

在模式串  abaabaca中。对应的next串为:01122341

Next[j]表示,在j匹配出错之后。要利用前面的子串,所能使用的子串长度+1。

至于next[j]表示的是什么。查了好多也不知道干什么用的。如果读者对next函数有了解,请留言。

参考博客:http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html

时间: 2024-10-03 23:10:18

字符串模式匹配算法--详解KMP算法的相关文章

常用算法3 - 字符串查找/模式匹配算法(BF & KMP算法)

相信我们都有在linux下查找文本内容的经历,比如当我们使用vim查找文本文件中的某个字或者某段话时,Linux很快做出反应并给出相应结果,特别方便快捷! 那么,我们有木有想过linux是如何在浩如烟海的文本中正确匹配到我们所需要的字符串呢?这就牵扯到了模式匹配算法! 1. 模式匹配 什么是模式匹配呢? 模式匹配,即子串P(模式串)在主串T(目标串)中的定位运算,也称串匹配 假设我们有两个字符串:T(Target, 目标串)和P(Pattern, 模式串):在目标串T中查找模式串T的定位过程,称

详解KMP算法

KMP算法应该是每一本<数据结构>书都会讲的,算是知名度最高的算法之一了,但很可惜,我大二那年压根就没看懂过~~~ 之后也在很多地方也都经常看到讲解KMP算法的文章,看久了好像也知道是怎么一回事,但总感觉有些地方自己还是没有完全懂明白.这两天花了点时间总结一下,有点小体会,我希望可以通过我自己的语言来把这个算法的一些细节梳理清楚,也算是考验一下自己有真正理解这个算法. 什么是KMP算法: KMP是三位大牛:D.E.Knuth.J.H.Morris和V.R.Pratt同时发现的.其中第一位就是&

[转] 字符串模式匹配算法——BM、Horspool、Sunday、KMP、KR、AC算法一网打尽

字符串模式匹配算法——BM.Horspool.Sunday.KMP.KR.AC算法一网打尽 转载自:http://dsqiu.iteye.com/blog/1700312 本文内容框架: §1 Boyer-Moore算法 §2 Horspool算法 §3 Sunday算法 §4 KMP算算法 §5 KR算法 §6 AC自动机 §7 小结 §1 Boyer-Moore(BM)算法 Boyer-Moore算法原理 Boyer-Moore算法是一种基于后缀匹配的模式串匹配算法,后缀匹配就是模式串从右到

Java数据结构之字符串模式匹配算法---Brute-Force算法

模式匹配 在字符串匹配问题中,我们期待察看源串 " S串 " 中是否含有目标串 " 串T " (也叫模式串).其中 串S被称为主串,串T被称为子串. 1.如果在主串中查找到子串,则称为模式匹配成功,返回模式串的第一个字符在主串中出现的位置. 2.如果在主串中未找到子串,则称为模式匹配失败,返回-1. 在模式匹配过程中有两个比较经典的算法:Brute-Force与KMP算法是两种最经典的模式匹配算法. 在本片中主要分析BF算法,很黄很暴力.下面是简单的思路解析:  

C#中的IDisposable模式用法详解

本文实例讲述了C#中IDisposable模式的用法,针对垃圾资源的回收进行了较为详细的讲解.分享给大家供大家参考之用.具体方法如下: 首先,对于垃圾回收而言,在C#中,托管资源的垃圾回收是通过CLR的Garbage Collection来实现的,Garbage Collection会调用堆栈上对象的析构函数完成对象的释放工作:而对于一些非托管资源,比如数据库链接对象等,需要实现IDisposable接口进行手动的垃圾回收.那么什么时候使用Idisposable接口,以及如何使用呢? 先来参考一

LVS负载均衡群集(三种工作模式原理详解)

LVS负载均衡群集(三种工作模式原理详解) 一.前言 ? 在互联网应用中,随着站点对硬件性能.响应速度.服务稳定性.数据可靠性等要求越来越高,单台服务器力不从心.所以我们需要通过一些方法来解决这样的瓶颈. ? 最简单的方法就是使用价格昂贵的大.小型的主机:但这样在大多数企业中显然是不可取或者说不现实的.那么我们就需要通过多个普通服务器构建服务器群集. 二.相关概念概述 2.1何为LVS? ? LVS--Linux Virtual Server,即Linux虚拟服务器(虚拟主机.共享主机),虚拟主

Python学习入门教程,字符串函数扩充详解

因有用户反映,在基础文章对字符串函数的讲解太过少,故写一篇文章详细讲解一下常用字符串函数.本文章是对:程序员带你十天快速入门Python,玩转电脑软件开发(三)中字符串函数的详解与扩充. 如果您想学习并参与本教程的完善与写作.请在下方讨论区,回复相关问题.一起完善本文章教程的书写. Python字符串常用函数. 声明字符串变量: str = ‘关注做全栈攻城狮,写代码也要读书,爱全栈,更爱生活.’ 下面所有字符串函数函数,是对变量str进行操作: 求字符串长度: 函数使用: 运行结果: 值得注意

Java多线程编程中Future模式的详解&lt;转&gt;

Java多线程编程中,常用的多线程设计模式包括:Future模式.Master-Worker模式.Guarded Suspeionsion模式.不变模式和生产者-消费者模式等.这篇文章主要讲述Future模式,关于其他多线程设计模式的地址如下:关于其他多线程设计模式的地址如下:关于Master-Worker模式的详解: Java多线程编程中Master-Worker模式的详解关于Guarded Suspeionsion模式的详解: Java多线程编程中Guarded Suspeionsion模式

工厂模式IDAL详解

IDAL 一. IDAL主要功能: 1.这完全是"工厂模式"的一部分实现而已 2.这是一组接口类,其中包括了每个要公开的数据访问方法.为每个数据库产品单独编写的DAL(数据访问层)都要实现这组接口所定义的方法 3.也就是规定了在DAL中编写的"对用户账号进行操作的类"所必须执行的方法! 4.IDAL要达到的目的是:实现业务逻辑(BLL)与数据库访问(DAL)的完全分离!!! 5.IDAL各个类(IDAL文件夹中的各个文件)划分或者说编制的原则,更趋向于"将