给你两个字符串a(len[a]=n),b(len[b]=m),问b是否是a的子串,并且统计b在a中的出现次数,如果我们枚举a从什么位置与匹配,并且验证是否匹配,那么时间复杂度O(nm),

而n和m的范围为10^5,这样做显然超时,因此我们就要用到神奇的KMP算法,在O(n)的时间内解决这一类的问题。

首先给出两个字符串

A:abababaababacb

B:ababacb

首先我们思考朴素算法,我们枚举A串的每一位作为开始与B串匹配的位置,然后一位一位进行检验,如果匹配失败则会从B串的开始重新匹配,这也是朴素算法为什么会超时的原因所在,那么我们可不可以不从B串的开始与A串的下一位匹配,而是直接找到一个可以与A串枚举到的那一位匹配的B串的一个位置,这样我们只需要扫描一遍字符串A,然后在更新可以匹配到B串的哪一个位置。

举个例子:

对于字符串A,B,他们的前五位是一样的,可以匹配。

但是第6位就无法匹配了,所以我们需要调整B串的位置重新匹配,通过观察我们发现B串的前3位和A串的3到5位可以匹配,所以我们可以直接将j的值改为3,然后继续和A串匹配。

这样一来我们就又可以继续向后匹配了。

但是i=8时又无法匹配了,我们需要继续调整B串的位置以便于进行匹配。

然而这样仍然不能匹配,那就继续移动,直至可以匹配为止。

最终我们成功将A串与B串匹配成功。

我们根据B串的移动规律可以构造出这样的一个p数组,使得p[j]表示B[1…j]=B[j-k+1…j]的k的最大值(即B串前j个字符最长相同的前缀和后缀的长度),这样我们就可以直接将B串进行上述的移动操作了。

 void kmp()
{
int j=;
for(int i=;i<n;i++)
{
while(j>&&b[j+]!=a[i+]) j=p[j];//如果下一位不能匹配就移动B串
if(b[j+]==a[i+]) j++;//如果可以匹配就继续匹配下一位
if(j==m)//这里表示完全匹配,也就是A串和B串成功匹配了
{
printf("%d\n",i-m+);
j=p[j];//这样的目的是为了不遗漏重叠的匹配
}
}
}

kmp匹配

接下来我们思考如何求这个p数组,假如我们知道了p[1…j-1]的值,那我们如何求p[j]的值呢?如果B[i+1]==B[j+1],那么显然p[j]=p[j-1]+1,因为这相当于前缀后缀都加了一个相同的字符,总长都加上1,那么若果B[i+1]!=B[j+1]我们可以考虑将j向后退一步,也就是减小j的值,再进行匹配。

 void pre()
{
p[]=;
int j=;
for(int i=;i<m;i++)
{
while(j>&&b[i+]!=b[j+]) j=p[j];
if(b[i+]==b[j+]) j++;
p[i+]=j;
}
}

求p数组

这样我们就成功完成了kmp算法

字符串(2)KMP算法的更多相关文章

  1. [Algorithm] 字符串匹配算法——KMP算法

    1 字符串匹配 字符串匹配是计算机的基本任务之一. 字符串匹配是什么?举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串& ...

  2. 字符串匹配算法——KMP算法

    处理字符串的过程中,难免会遇到字符匹配的问题.常用的字符匹配方法 1. 朴素模式匹配算法(Brute-Force算法) 求子串位置的定位函数Index( S, T, pos). 模式匹配:子串的定位操 ...

  3. 查找字符串的 KMP 算法

    查找字符串是我们平常编程过程中经常遇到的,现在介绍一种查找字符串算法,增加程序的执行速度. 通常我们是这么写的: /* content: search a string in a othor stri ...

  4. 字符串匹配算法——KMP算法学习

    KMP算法是用来解决字符串的匹配问题的,即在字符串S中寻找字符串P.形式定义:假设存在长度为n的字符数组S[0...n-1],长度为m的字符数组P[0...m-1],是否存在i,使得SiSi+1... ...

  5. 字符串模式匹配KMP算法

    一篇不错的博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html KMP字符串模式匹配通俗点说就是一种在一个字符串中 ...

  6. 字符串查找KMP算法(转)

    如果你用过ctrl+F这个快捷键,那么你有很大的概率使用过这个算法,这就是在待查找字符串(可能有成千上万个字符)中找出模式串(比较小,可能有几个字符),可能找到大于或者等于1次的位置.例如,在abab ...

  7. 字符串查找KMP算法

    如果你用过ctrl+F这个快捷键,那么你有很大的概率使用过这个算法,这就是在待查找字符串(可能有成千上万个字符)中找出模式串(比较小,可能有几个字符),可能找到大于或者等于1次的位置.例如,在abab ...

  8. c算法:字符串查找-KMP算法

    /* *用KMP算法实现字符串匹配搜索方法 *该程序实现的功能是搜索本目录下的所有文件的内容是否与给定的 *字符串匹配,如果匹配,则输出文件名:包含该字符串的行 *待搜索的目标串搜索指针移动位数 = ...

  9. 字符串匹配算法-kmp算法

    一原理: 部分转自:http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html 字 ...

  10. 字符串匹配算法KMP算法

    数据结构中讲到关于字符串匹配算法时,提到朴素匹配算法,和KMP匹配算法. 朴素匹配算法就是简单的一个一个匹配字符,如果遇到不匹配字符那么就在源字符串中迭代下一个位置一个一个的匹配,这样计算起来会有很多 ...

随机推荐

  1. Node之安装篇

    本篇主要介绍node的安装与相关配置 官网: https://nodejs.org/en/ Linux: Windows:

  2. Express使用art-template模板引擎

    第一步:安装 npm install --save art-template npm install --save express-art-template 第二步:指定.html使用的解析引擎(官方 ...

  3. CSS3文字、背景与列表

    一.文本相关属性 1.字体 (1)字体设置 在HTML中,字体通过<font face="字体名称">来设置.在CSS中字体通过font-family属性来控制,里面可 ...

  4. Nginx集群session管理的两种方式

    1.IP_HASH 修改nginx配置文件 实现非常简单,但是绑定在一个服务器上了,不能跨越多个服务. 2.redis管理 管理session信息的空间,需要修改tomcat配置文件 下载相应的red ...

  5. CSS代码检查工具stylelint

    前面的话 CSS不能算是严格意义的编程语言,但是在前端体系中却不能小觑. CSS 是以描述为主的样式表,如果描述得混乱.没有规则,对于其他开发者一定是一个定时炸弹,特别是有强迫症的人群.CSS 看似简 ...

  6. error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\BIN\\x86_amd64\\cl.exe' failed with exit status 2

    安装mysql是出现这个错误. python3.和python2.两个的版本不一样,所以安装的东西也不一样:MySQLdb 安装mysql的连接包.工具安装 Python3.x版本:Pip insta ...

  7. Unity3d中如何查找一个脚本被挂在那些预设上面?

    用一个脚本函数可以获取到选择的脚本文件被哪些预设和场景引用 [MenuItem("Assets/Tool/GetReference")] static void GetRefere ...

  8. opencv 图片位移

    import cv2 as cv import numpy as np # 图片移位 img = cv.imread('../images/moon.jpg', flags=1) # flags=1读 ...

  9. 【UR #7】水题走四方

    题目描述 今天是世界水日,著名的水题资源专家蝈蝈大臣发起了水题走四方活动,向全世界发放成千上万的水题. 蝈蝈大臣是家里蹲大学的教授,当然不愿意出门发水题啦!所以他委托他的助手欧姆来发. 助手欧姆最近做 ...

  10. OS + CentOS / http_proxy / https_proxy / dalishangwang / repo

    s OS + Linux RedHat / redhat7 / redhat 7 / redhat 6 / redhat 5 https://lindows.iteye.com/blog/456637 ...