- 浏览: 262626 次
- 性别:
- 来自: 大连
文章分类
最新评论
-
saishangxue123:
文章写的清楚、明了,一气呵成,支持
什么是反射、反射能干什么、如何使用反射? -
allen3010:
1,2,3,4,5这六个数字。。。。。
用1、2、2、3、4、5这六个数字,用java写一个main函数,打印出所有不同的排列
http://www.cnblogs.com/huangxincheng/archive/2012/12/01/2796993.html
在大学的时候,应该在数据结构里面都看过kmp算法吧,不知道有多少老师对该算法是一笔带过的,至少我们以前是的,
确实kmp算法还是有点饶人的,如果说红黑树是变态级的,那么kmp算法比红黑树还要变态,很抱歉,每次打kmp的时候,输
入法总是提示“看毛片”三个字,嘿嘿,就叫“看毛片算法”吧。
一:BF算法
如果让你写字符串的模式匹配,你可能会很快的写出朴素的bf算法,至少问题是解决了,我想大家很清楚的知道它的时间复
杂度为O(MN),原因很简单,主串和模式串失配的时候,我们总是将模式串的第一位与主串的下一个字符进行比较,所以复杂
度高在主串每次失配的时候都要回溯,图我就省略了。
二:KMP算法
刚才我们也说了,主串每次都要回溯,从而提高了时间复杂度,那么能不能在“主串”和“模式串”失配的情况下,主串不回溯呢?
而是让”模式串“向右滑动一定的距离,对上号后继续进行下一轮的匹配,从而做到时间复杂度为O(M+N)呢?所以kmp算法就是
用来处理这件事情的,下面我们看下简单的例子。
在大学的时候,应该在数据结构里面都看过kmp算法吧,不知道有多少老师对该算法是一笔带过的,至少我们以前是的,
确实kmp算法还是有点饶人的,如果说红黑树是变态级的,那么kmp算法比红黑树还要变态,很抱歉,每次打kmp的时候,输
入法总是提示“看毛片”三个字,嘿嘿,就叫“看毛片算法”吧。
一:BF算法
如果让你写字符串的模式匹配,你可能会很快的写出朴素的bf算法,至少问题是解决了,我想大家很清楚的知道它的时间复
杂度为O(MN),原因很简单,主串和模式串失配的时候,我们总是将模式串的第一位与主串的下一个字符进行比较,所以复杂
度高在主串每次失配的时候都要回溯,图我就省略了。
二:KMP算法
刚才我们也说了,主串每次都要回溯,从而提高了时间复杂度,那么能不能在“主串”和“模式串”失配的情况下,主串不回溯呢?
而是让”模式串“向右滑动一定的距离,对上号后继续进行下一轮的匹配,从而做到时间复杂度为O(M+N)呢?所以kmp算法就是
用来处理这件事情的,下面我们看下简单的例子。
通过这张图,我们来讨论下它的一般推理,假设主串为S,模式串为P,在Si != Pj的时候,我们可以看到满足如下关系式 Si-jSi-j+1...Sn-1=P0P1..Pj-1。那么模式P应该向右滑动多少距离?也就是主串中的第i个字符应与模式串中的哪一个字符进行比较? 假设应该与模式串中的第k的位置相比较,假如模式串中存在最大的前缀真子串和后缀真子串,那么有P0P1..Pk-1=Pj-kPj-k+1...Pj-1. 这句话的意思也就是说,在模式P中,前k个字符与j个字符之前的k个字符相同,比如说:“abad”的最大前缀真子串为“aba",最大 后缀真子串为“bad”,当然这里是不相等,这里的0<k<j,我们希望k接近于j,那么我们滑动的距离将会最小,好吧,现在我们用 next[j]来记录失配时模式串应该用哪一个字符于Si进行比较。 设 next[j]=k。根据公式我们有 -1 当j=0时 next[j] = max{k| 0<k<j 且 P0P1..Pk-1=Pj-kPj-k+1...Pj-1} 0 其他情况 好,接下来的问题就是如何求出next[j],这个也就是kmp思想的核心,对于next[j]的求法,我们采用递推法,现在我们知道了 next[j]=k,我们来求next[j+1]=?的问题?其实也就是两种情况: ①:Pk=Pj 时 则P0P1...Pk=Pj-kPj-k+1...Pj, 则我们知: next[j+1]=k+1。 又因为next[j]=k,则 next[j+1]=next[j]+1。 ②:Pk!=Pj 时 则P0P1...Pk!=Pj-kPj-k+1...Pj,这种情况我们有点蛋疼,其实这里我们又将模式串的匹配问题转化为了上面我们提到 的”主串“和”模式串“中寻找next的问题,你可以理解成在模式串的前缀串和后缀串中寻找next[j]的问题。现在我们的思路就是一定 要找到这个k2,使得Pk2=Pj,然后将k2代入①就可以了。 设 k2=next[k]。 则有P0P1...Pk2-1=Pj-k2Pj-k2+1...Pj-1。 若 Pj=Pk2, 则 next[j+1]=k2+1=next[k]+1。 若 Pj!=Pk2, 则可以继续像上面递归的使用next,直到不存在k2为止。 好,下面我们上代码,可能有点绕,不管你懂没懂,反正我懂了。 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace SupportCenter.Test 7 { 8 public class Program 9 { 10 static void Main(string[] args) 11 { 12 string zstr = "ababcabababdc"; 13 14 string mstr = "babdc"; 15 16 var index = KMP(zstr, mstr); 17 18 if (index == -1) 19 Console.WriteLine("没有匹配的字符串!"); 20 else 21 Console.WriteLine("哈哈,找到字符啦,位置为:" + index); 22 23 Console.Read(); 24 } 25 26 static int KMP(string bigstr, string smallstr) 27 { 28 int i = 0; 29 int j = 0; 30 31 //计算“前缀串”和“后缀串“的next 32 int[] next = GetNextVal(smallstr); 33 34 while (i < bigstr.Length && j < smallstr.Length) 35 { 36 if (j == -1 || bigstr[i] == smallstr[j]) 37 { 38 i++; 39 j++; 40 } 41 else 42 { 43 j = next[j]; 44 } 45 } 46 47 if (j == smallstr.Length) 48 return i - smallstr.Length; 49 50 return -1; 51 } 52 53 /// <summary> 54 /// p0,p1....pk-1 (前缀串) 55 /// pj-k,pj-k+1....pj-1 (后缀串) 56 /// </summary> 57 /// <param name="match"></param> 58 /// <returns></returns> 59 static int[] GetNextVal(string smallstr) 60 { 61 //前缀串起始位置("-1"是方便计算) 62 int k = -1; 63 64 //后缀串起始位置("-1"是方便计算) 65 int j = 0; 66 67 int[] next = new int[smallstr.Length]; 68 69 //根据公式: j=0时,next[j]=-1 70 next[j] = -1; 71 72 while (j < smallstr.Length - 1) 73 { 74 if (k == -1 || smallstr[k] == smallstr[j]) 75 { 76 //pk=pj的情况: next[j+1]=k+1 => next[j+1]=next[j]+1 77 next[++j] = ++k; 78 } 79 else 80 { 81 //pk != pj 的情况:我们递推 k=next[k]; 82 //要么找到,要么k=-1中止 83 k = next[k]; 84 } 85 } 86 87 return next; 88 } 89 } 90 }
发表评论
-
java时间大小比较
2015-04-02 21:48 999摘自: http://blog.sina.com.cn/s/b ... -
StringBuffer的常用方法
2015-03-30 16:06 992摘自:http://blog.csdn.net/deaful/ ... -
什么是反射、反射能干什么、如何使用反射?
2013-08-16 00:03 4887//来源互联网 一、什 ... -
Class.forName···关于Class. 的应用介绍
2013-08-15 23:36 1188//摘自互联网 Class.forName(xxx.xx ... -
java泛型map的用法(转2)
2013-07-25 23:04 92311.声明一个map: Map map = ne ... -
java泛型map的用法(转)
2013-07-25 22:56 3149http://www.apkbus.com/blog-2079 ... -
关于日期 Date Calendar
2013-07-23 22:46 1160import java.security.Timestam ... -
正则表达式 例子
2013-07-22 23:00 849import java.util.regex.Matche ... -
Iterator的使用方法
2013-07-18 21:45 0import java.util.*; publ ... -
泛型的写法种种
2013-07-18 21:41 1056public class Generics<T> ... -
ArrayList ,LinkedList, TreeSet的使用方法
2013-07-18 21:35 2350import java.util.*; public ... -
Stack的使用方法
2013-07-18 21:26 1398import java.util.Stack; ... -
Hashtable的使用方法介绍
2013-07-18 21:24 23161**************************** ... -
老式枚举的使用方法
2013-07-18 21:23 974import java.util.Enumeration; ... -
java中Map的各种排序介绍
2013-07-14 13:24 1750//本篇来源于互联网 HashMap: 最常用的Ma ... -
java配置文件用法
2013-04-14 22:43 1331package cn.com.mfsoft.config; ... -
java利用反射得到实例
2013-04-10 22:44 1304对于面向接口编程的项目免不了要一反射相接触,动态得到实例: ... -
spring的beanFactory和factoryBean
2013-04-05 16:10 2160spring的beanFactory和factoryBe ... -
Spring配置文件总结
2013-04-05 16:05 908Spring配置文件总结(转) 2010-06-07 23: ... -
Spring 的微内核与FactoryBean扩展机制
2013-04-05 15:49 1639Spring 的微内核与FactoryBean扩展机制 ...
相关推荐
算法 KMP算法 KMP算法 KMP算法 KMP算法 KMP算法 KMP算法 KMP算法 KMP算法 KMP算法 KMP算法 KMP算法 KMP
KMP算法,全称为Knuth-Morris-Pratt算法,是一种高效的字符串匹配算法,由Donald Knuth、Vaughan Morris和Robert Pratt三位学者提出。它的主要目标是在一个长字符串(主串A)中查找是否存在一个指定的短字符串(模式...
### 数据结果 KMP算法实验报告 #### 实验背景与目的 本实验主要针对《数据结构》课程中的字符串处理部分,具体涉及的是模式匹配算法——KMP算法。通过实验加深学生对串类型及其基本操作的理解,并重点掌握两种重要...
KMP算法,全称为Knuth-Morris-Pratt算法,是一种在字符串中寻找子串的高效搜索算法。它由D.E. Knuth、V. Morris和J.H. Pratt三位学者于1970年提出,主要用于解决模式匹配问题。传统的KMP算法避免了不必要的字符比较...
KMP算法是一种改进的字符串匹配算法,由Donald Knuth、Morris和Frank Pratt共同提出,其主要特点是在匹配过程中能够避免不必要的字符比较,从而提高搜索效率。 KMP算法的核心思想是构建一个部分匹配表(也称为失败...
`KMP算法.cpp`文件应该包含了这些实现逻辑,通过编译生成的`KMP算法.exe`可执行文件可以直接运行并测试。 4. **性能分析** KMP算法的时间复杂度为O(n + m),其中n为主串长度,m为子串长度。这是因为即使最坏情况下...
**KMP算法实现模板(C++版) ACM算法** KMP(Knuth-Morris-Pratt)算法是一种在文本字符串中查找子串匹配的有效方法,尤其适用于已经预处理了模式串(子串)的匹配信息。它是由D.E. Knuth、V. Morris和J.H. Pratt...
用C++语言实现的KMP算法。经过调试。供广大算法学习者参考。
"模式匹配的KMP算法" 模式匹配的KMP算法是计算机科学领域中的一种经典算法,用于解决串的模式匹配问题。该算法可以高效地查找目标串中是否包含某个模式串,并返回模式串在目标串中的起始位置。 模式匹配的KMP算法...
《字符串模式匹配KMP算法》教学课例设计 在这篇教学设计中,我们旨在帮助学生掌握KMP字符串模式匹配算法的基本概念和应用。通过本课例设计,学生将了解KMP算法的应用普遍性、实现机制和时间复杂度,并掌握计算next...
数据结构中的KMP算法是一种高效的字符串匹配算法,由D.E.Knuth、V.J.Morris和J.H.Pratt三位学者提出,因此得名KMP(Knuth-Morris-Pratt)。该算法主要用于在一个文本串中查找一个模式串(即目标字符串)是否存在。...
数据结构、kmp算法、代码实现、KMP(char *P,char *T,int *N,int start)
DS串应用--KMP算法DS串应用--KMP算法DS串应用--KMP算法DS串应用--KMP算法
BF 算法和 KMP 算法在字符串匹配中的应用 BF 算法和 KMP 算法是两种常用的字符串匹配算法,分别应用于不同的场景中。本文将对这两种算法进行详细的分析和比较,以便更好地理解它们的原理和应用。 BF 算法 BF ...
模式匹配中的KMP算法的实现 模式匹配是计算机科学领域中的一个研究热点,串的模式匹配算法是其中的一个重要分支。在模式匹配中,KMP算法是一个非常重要的算法,它可以高效地实现串的模式匹配。下面我们将详细介绍...
### 字符串KMP算法C语言实现解析 在计算机科学领域,字符串匹配是常见的操作之一,其中KMP算法(Knuth-Morris-Pratt算法)因其高效性而被广泛使用。KMP算法由Donald Knuth、James H.Morris以及Vaughan Pratt共同...
KMP算法,全称Knuth-Morris-Pratt算法,是一种高效的字符串匹配算法,由Donald Knuth、James H. Morris和 Vaughan Pratt三位学者在1970年提出。该算法主要用于解决在一个大文本串(A)中查找是否存在一个指定的小...
数据结构中KMP算法过程的Flash演示
在数据结构和算法的学习中,理解并掌握KMP算法对于解决字符串匹配问题至关重要。 KMP算法的核心是构建一个“部分匹配表”(也称为“失败指针”或“前缀函数”),它记录了子字符串的每一个前缀和后缀的最大公共长度...
kmp算法 KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。KMP算法的关键是利用匹配失败后的信息,尽量减少模式串...