KMP算法专门用于处理字符串匹配问题。

开始学习的时候觉得很有道理,但是一些细节总觉得有些模糊,所以一直觉得懵懵懂懂。今天思考了一下,总结一下,希望对大家也有帮助。

朴素的字符串匹配算法就是一个一个字符挨个去试,但是当匹配串长度比较长的时候复杂度显然会爆炸。

为了解决这个问题,很厉害的三个人想出来了这个很厉害的算法。

核心思想是假如比较到第j+1个字符的时候匹配失败,不是像朴素算法一样从头开始比较,而是利用匹配串自身的特性直接跳转到匹配串头部,这个头部和尾部相同。这是比较容易理解的,显然这样做是正确的,但是为什么能够保证不会漏掉可能存在的其他匹配串呢?

现在我们用反证法来看这个问题:即假在串s1中查找串s2,如果比较到si的第i个元素,s2的第j个元素,发现s1[i+1]!=s2[j+1],此时我们可以直接跳转到s2[p[j]]处继续匹配s1和s2,p[j]是指s2[1..p[j]]和s2[i-p[j]+1..i]相同的最大p[j],现在证明这样做不会漏掉前面(s1[i-j+1..i-p[j]+1]这些部分是没有进行比较的)可能存在的其他串。

假如在那个区域存在与s2匹配的串,因为长度问题,这个串结束的部分一定超过i,而这个串在i前面的部分和s2[1..j]相同,但是它比最大的p[j]还长,这样的串是不可能存在的,同时也说明了为什么KMP需要最大的p[j]。

现在基本思想已经证明正确,所要做的就是思考如何实现这个算法了。问题主要有两个:如何得到p[j]和如何实现匹配算法。

为了方便理解,这里先介绍如何实现匹配算法:

 1 void kmp()
2 {
3 j=0;//匹配串的指针
4 for(int i=0;i<n;i++) //之所以是小于n是因为会判断i+1处的值
5 {
6 while(j>0 && a[i+1]!=b[j+1]) j=p[j];//j>0说明在j前面存在匹配,存在匹配而出现不匹配就要将j指针前移到和末尾相同而且下一位支持匹配的地方
7 if(b[j+1]==a[i+1]) ++j;
8 if(j==m)
9 {
10 printf("%d",i+1-m+1);//直接输出匹配位置
11 j=p[j]; //继续寻找(可重叠)匹配
12 //j=0; 寻找不重叠匹配
13 }
14 }
15 }

这个过程的复杂度为O(n),具体为什么需要进行摊还分析(我也不是太懂。。。)。

然后我们就要考虑如何得到p[j]了。

我们不难发现(不难个鬼哦),在求p[j]的过程其实就是在前j-1个字符中查找第j个位置组成的子串的过程,因此得到p[j]的过程其实和上述过程类似不同之处在于每次查找结束后都要更新那个位置的p[j]的值。

 1 void pre()
2 {
3 p[1]=0;
4 j=0; //j指i所匹配的位置
5 for(int i=1;i<m;i++)
6 {
7 while(j>0 && b[j+1]!=b[i+1]) j=p[j];
8 if(b[i+1]==b[j+1]) ++j;
9 p[i+1]=j;
10 }
11 }

大概就是这样,嗯~

KMP初步的更多相关文章

  1. kmp算法初步理解

    123456789 abbdaxnds Next   01212 第三位看第二位b,第二位和第三位相同,都是b,所以第三位的next是第二位的next加1,即1+1=2 第四位看第三位b,第四位d与第 ...

  2. Number Sequence HDU 1711(KMP)

    http://acm.hdu.edu.cn/showproblem.php?pid=1711 首次接触KMP,自己都不是特别理解.在网上百度看了好几个帖子之后,对KMP也有了初步的理解. #inclu ...

  3. KMP算法中next函数的理解

    首先要感谢http://blog.csdn.net/v_july_v/article/details/7041827以及http://blog.chinaunix.net/uid-27164517-i ...

  4. KMP算法具体解释(转)

    作者:July. 出处:http://blog.csdn.net/v_JULY_v/. 引记 此前一天,一位MS的朋友邀我一起去与他讨论高速排序,红黑树,字典树,B树.后缀树,包含KMP算法,只有在解 ...

  5. 完全掌握KMP算法思想

    文档下载页面http://download.csdn.net/detail/yedeqixian/4209500      80页在讲KMP算法的开始先举了个例子,让我们对KMP的基本思想有了最初的认 ...

  6. KMP字符串匹配 简单理解

    http://www.cnblogs.com/c-cloud/p/3224788.html 字符串匹配,长串长度为m,子串长度为n 则,暴力破解的复杂度为o(m*n) 如果用kmp匹配,则复杂度为o( ...

  7. 字符串匹配(KMP 算法 含代码)

    主要是针对字符串的匹配算法进行解说 有关字符串的基本知识 传统的串匹配法 模式匹配的一种改进算法KMP算法 网上一比較易懂的解说 小样例 1计算next 2计算nextval 代码 有关字符串的基本知 ...

  8. POJ2406 Power Strings —— KMP or 后缀数组 最小循环节

    题目链接:https://vjudge.net/problem/POJ-2406 Power Strings Time Limit: 3000MS   Memory Limit: 65536K Tot ...

  9. 移动端之Android开发的几种方式的初步体验

    目前越来越多的移动端混合开发方式,下面列举的大多数我都略微的尝试过,就初步的认识写个简单的心得: 开发方式 开发环境 是否需要AndroidSDK 支持跨平台 开发语言&技能 MUI Win+ ...

随机推荐

  1. 初学python之路-day02

    python,诞生于1989年的圣诞,Guido van Rossum为了打发无聊,因此发明了python,并且开放了其源代码,使得这门语言在随后的几十年的发展的越来越广.现今,2.x版本已经在2.7 ...

  2. java的官网下载(如有不懂,可以去我发的视频网站,那里面有详细过程)

    https://www.oracle.com/technetwork/java/javase/downloads/java-archive-javase9-3934878.html java 9的下载 ...

  3. 【python】随机数用法

    全文拷贝自:Python随机数用法 random.seed(int) 给随机数对象一个种子值,用于产生随机序列. 对于同一个种子值的输入,之后产生的随机数序列也一样. 通常是把时间秒数等变化值作为种子 ...

  4. vue中html模板使用绑定的全局函数

    我们知道在script中使用vue绑定的全局函数时, 我们需要用这种方式使用: this.Util.Fun(e) 那在模板中, 比如v-if中想使用Fun函数怎么办呢?你应该这样做 <i v-i ...

  5. python 2.7 数据结构之列表list: 基础面试总结

    python 列表函数及方法: 函数如下: 1 cmp(list1,list2) 比较两个列表中的元素 2 len(list) 列表元素个数 3 max(list) 返回列表元素最大值 4 min(l ...

  6. Visual Studio 2017

    美国西雅图时间 3 月 7 日上午 9 点(北京时间 8 日凌晨 1 点),微软将正式发布 Visual Studio 2017.   下载地址:https://www.visualstudio.co ...

  7. 利用fastjson解析json并通过js&ajax实现页面的无跳转刷新

    1.json是一种优秀的数据格式,在移动开发和web开发中经常用到,本例中通过一个小案例讲解如何通过alibaba的开源框架fastjson来解析jason数据格式并通过js实现无跳转刷新 2,新建一 ...

  8. lambda表达式——写多线程

    JDK1.8 中Lambda 表达式的出现,基本可以取替原来的匿名类实现多线程的方式.下面列举常用的常用的三种情况. 一.普通开启异步线程   new Thread(() -> System.o ...

  9. JS对象的拷贝

    1:对数据进行备份的时候,如果这个数据是基本的数据类型,那么很好办,通过赋值实现复制即可. 赋值与浅拷贝的区别 var obj1 = { 'name' : 'zhangsan', 'age' : '1 ...

  10. 网页布局之grid

    学习网格布局时,你可能会在网络上看到很多文章,内容不同,属性不同,真是让人摸不着头脑,到底哪个才是正确的?看了本篇文章,我想你会豁然开朗.比如,一会儿用grid-rows,一会儿用grid-defin ...