KMP算法匹配字符串

朴素匹配算法

  字符串的模式匹配的方法刚开始是朴素匹配算法,也就是经常说的暴力匹配,说白了就是用子串去和父串一个一个匹配,从父串的第一个字符开始匹配,如果匹配到某一个失配了,就重新去从父串的下一个字符开始匹配,这样的算法虽然理解起来容易,但是算法的时间复杂度无疑是很高的,假如父串是一个很长的字符串,而字串恰恰不和父串匹配,那无疑是对CPU的迫害。

  下面贴几张图看看这种朴素匹配算法:

但是第四个出现失配,就得重新让字串去和父串的第二个字符匹配,发现第二个也不匹配,只能再次匹配第三个,如下:

  这样下来时间复杂度大大变高,但是通过上帝视角我们可以发现其实第二个完全不用试,但是计算机不知道啊,所以我们就需要一个更好的算法来解决这个问题,这个算法就是要在朴素算法的基础上额外告诉计算机哪些地方不用尝试,可能我上面的这个例子举得不太恰当,但是这个算法的额外功能就是告诉了计算机如果某个位置失配了应该去尝试哪个位置。

  

KMP算法——和计算机的友好交流

  前面我们说KMP算法其实就是告诉计算机如果某个位置失配后应该往哪个位置回溯。而这个功能的实现其实只需要一个next数组,而这个数组也恰恰是这个算法的核心所在。

next数组

  这个数组里面存储的就是字串中每个位置失配后应该回溯的下标。举个例子,比如第9个元素失配后应该回溯到第3个再次匹配尝试,那就应该是next[9] = 3,值得注意的是,我们定义的串这个数据结构一般没有0号元素,所以next数组一样,next[0]没有意义。

  next数组该如何实现呢?

比如这块我们发现1-7和9-15都相等,而8和16不相等,那如果在第16个位置发生失配,就可以用1-7依次替代9-15的位置,用第8个再去匹配,如果匹配上了就继续往下匹配,未匹配就继续回溯。

代码实现(next数组):

void get_next(string son, int* next)
{
int i = 1; //下标
int j = 0; //回去的位置
next[1] = 0;
/*因为字符串未设置0号元素,所以next从1开始,默认为0,你应该懂我意思吧,回溯到0,你可能会问:
不是说好没有0号元素吗。你想啊,让字串的0号元素和父串的下一个匹配,难道不就是让字串的第一个和父串的
下一个匹配吗*/
while (i < son.len)
{
//如果这两个相等,即下标为i和j的元素相等,则当后面那个元素即i的下一个元素失配时,回溯到j的下一个元素,因为i和j的元素相等,所以保证了前面的一致,可以回溯
if (j == 0 || getch(son, i) == getch(son, j))
{
i++; j++; //精华,++后对应上面那句注释的 “当后面那个元素即i的下一个元素失配时,回溯到j的下一个元素”
if (getch(son, i) == getch(son, j)) //这里是一处优化,如果++后还相等,那你回溯回去肯定还失配啊,就再次回溯到你回溯的回溯
next[i] = next[j];
else
next[i] = j;
}
else //如果不相等,就将j回溯,i不能变,因为i一个一个加给next数组每个依次赋值
j = next[j];
}
}

KMP算法部分

  实现了next数组,剩下的就很简单了,利用next数组在失配时去回溯就ok了。

代码实现:

getch()函数是为了随机访问串

int kmp(string far, string son)
{
int next[255];
get_next(son, next);
int index = 1; //子串的下标索引
for (int i = 1; i <= far.len; i++) //遍历父串
{
while (index <= son.len)
{
if (getch(far, i) == getch(son, index))
{
index++; //如果匹配给子串+1
if (index == son.len + 1)
{
printf("成功!\n");
return i - son.len + 1;
}
break;
}
else
{
index = next[index];
if (index == 0)
{
index = 1;
break;
}
}
}
}
printf("失败!\n");
return 0;
}

字符串模式匹配——KMP算法的更多相关文章

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

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

  2. 数据结构4.3_字符串模式匹配——KMP算法详解

    next数组表示字符串前后缀匹配的最大长度.是KMP算法的精髓所在.可以起到决定模式字符串右移多少长度以达到跳跃式匹配的高效模式. 以下是对next数组的解释: 如何求next数组: 相关链接:按顺序 ...

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

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

  4. 字符串模式匹配sunday算法

    文字部分转自:http://www.cnblogs.com/mr-ghostaqi/p/4285868.html 代码是我自己写的 今天在做LeetCode的时候,碰到一个写字符串匹配的题目: htt ...

  5. 『字符串模式匹配 KMP』

    字符串模式匹配 我们要先了解一下问题是什么. 模式匹配是数据结构中字符串的一种基本运算,给定一个子串,要求在某个字符串中找出与该子串相同的所有子串,这就是模式匹配. KMP 然后我们来认识一下今天的主 ...

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

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

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

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

  8. 模式匹配KMP算法

    关于KMP算法的原理网上有很详细的解释,我试着总结理解一下: KMP算法是什么 以这张图片为例子 匹配到j=5时失效了,BF算法里我们会使i=1,j=0,再看s的第i位开始能不能匹配,而KMP算法接下 ...

  9. 查找字符串的 KMP 算法

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

随机推荐

  1. webpack-优化阻塞的css

    随着浏览器的日新月异,网页的性能和速度越来越好,并且对于用户体验来说也越来越重要. 现在有很多优化页面的办法,比如:静态资源的合并和压缩,code splitting,DNS预读取等等. 本文介绍的是 ...

  2. Web安全测试实战之测试HTTP方法

    一. Http方法测试 有些Web服务器默认情况下开放了一些不必要的HTTP方法(如DELETE.PUT.TRACE.MOVE.COPY),这样就增加了受攻击面. 测试方法: 1.打开webscara ...

  3. gitbook 入门教程之增强版 edit-link-plus 编辑此页插件

    Gitbook plugin add "edit this page" link, and intelligent recognition to Github or Gitlab ...

  4. android 点击无效验证

    背景 在写一个东西滑动删除列表的时候,出现了一个问题.我的需求是,左滑然后出现delete,然后点击delete,让该滑块消失. 我在点列表的第一行的时候,左滑,出现delete,点击删除,ok的,完 ...

  5. Java 将Excel转为PDF

    本文将介绍在Java程序中如何将Excel工作簿转为PDF文档的,包括: 将整个工作簿转为PDF 将指定工作表转为PDF   使用工具:Free Spire.XLS for Java (免费版) Ja ...

  6. 3D硬件加速提升动画性能 与 z-index属性

    目录 1. chrome Layer borders 2. 层创建标准 3. 例子 总结 1. chrome Layer borders <WebKit技术内幕>第二章介绍了网页的结构,其 ...

  7. 让外部的开发机直接访问Kubernetes群集内的服务!

    让外部的开发机直接访问Kubernetes群集内的服务! 1.场景 容器化+K8s编排已经是现在进行时把网站的多个项目设计为云原生(Cloud Native)或老项改造为云原生可以获得诸多能力例如无云 ...

  8. LAMP两种模式

    [LAMP] Linux(Centos)LAMP环境搭建,LAMP源码安装及LAMP架构原理详解 Wish_亮关注2人评论9469人阅读2018-08-20 01:33:10   本章blog主要介绍 ...

  9. 【Java Web开发学习】跨域请求

    [Java Web开发学习]跨域请求 ================================================= 1.使用jsonp ===================== ...

  10. 两个div,都设置未inline-block,可是在IE出现错位问题

    [实现要求] 红色的和黄色的内容撑开,蓝色包住红黄,不定框居中显示 [遇到问题] chrome显示正常,但是在IE上红黄框会出现错位的问题 [如何解决]  给红色框添加一个overflow:hidde ...