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. 【原创】大数据基础之HDFS(1)HDFS新创建文件如何分配Datanode

    HDFS中的File由Block组成,一个File包含一个或多个Block,当创建File时会创建一个Block,然后根据配置的副本数量(默认是3)申请3个Datanode来存放这个Block: 通过 ...

  2. 在浏览器中查看.vue文件的源码

  3. 递归遍历所有xml的节点及子节点

    import java.io.File; import java.util.List; import org.dom4j.Attribute; import org.dom4j.Document; i ...

  4. 结构体重载运算符&srand&rand

    先上代码,再按代码讲解 #include<stdio.h>#include<string.h>#include<stdlib.h>#include<time. ...

  5. Flask开发微电影网站(六)

    1. 后台管理登录功能实现 1.1 后台管理页面登录表单LoginForm 在app的admin目录下创建forms.py文件,用来保存admin蓝图中需要使用到的表单 from flask_wtf ...

  6. 绝对定位下margin的作用

    以前一直对绝对定位下的margin作用很模糊,今天细看一下 不使用top,left,margin等 <!DOCTYPE html> <html lang="en" ...

  7. 关于在windows上远行的虚拟机为ubuntu16.04中不能复制和粘贴的问题解决方案

    Linux安装 VMware tools 工具解决复制和粘贴的方法 VMware虚拟机中如何安装VMWare-Tools详解好处:可以支持图形界面,可以支持共享文件功能等 1 工具/原料 1)安装过虚 ...

  8. django 第四天

    简单的一对多的页面 实现的页面结果如下 利用正则匹配 1.x系列和2.x系列django的用法不同,....他x的. 关于正则匹配 我一直没能实现,再试试吧 路由分发,尤其是在多个页面的时候 app0 ...

  9. Javascript实现的数组降维——维度不同,怎么谈恋爱(修订版)

    数组的元素可能是数组,这样一层层嵌套,可能得到一个嵌套很深的数组,数组降维要做的事就是把嵌套很深的数组展开,一般最后得到一个一维数组,其中的元素都是非数组元素,比如数组[1, [2, 3, [4, 5 ...

  10. 前端技术之--CSS

    在标签上设置style属性: background-color: #2459a2; height: 48px; ... 编写css样式: 1. 标签的style属性 2. 写在head里面 style ...